1、服务端
/*************************************************************************
> File Name: src/time_tcp_server.c
> Author: sicaolong
> Mail: sicaolong4@163.com
> Created Time: 2018年07月18日 星期三 20时22分42秒
************************************************************************/
#include<stdio.h>
#include<netdb.h>
#include<unistd.h>
#include<stdlib.h>
#include<memory.h>
#include<signal.h>
#include<time.h>
#include <arpa/inet.h>
int sockfd;
void sig_handler(int signo)
{
if(signo==SIGINT)
{
printf("server close\n");
//也属于步骤6 关闭socket;
close(sockfd);
exit(1);
}
}
//输出链接上来的客户端的相关的信息;
void out_addr(struct sockaddr_in *clientaddr)
{
//将端口从网络字节序转换成 主机字节序
int port =ntohs(clientaddr->sin_port);
char ip[16];
memset(ip,0,sizeof(ip));
//将ip地址从网络字节序转换成点分十进制;
inet_ntop(AF_INET,&clientaddr->sin_addr.s_addr,ip,sizeof(ip));
printf("client : %s(%d) connect \n",ip,port);
}
//
void do_service(int fd)
{
size_t len;
char buff[20];
if((len=read(fd,buff,20))<0)
perror("read error");
long t=time(0);
char *s=ctime(&t);
size_t size=strlen(s)*sizeof(char);
//将服务器断的系统时间协会到客户端中
if(write(fd,s,size)!=size)
{
perror("write error");
exit(1);
}
}
int main(int argc, char *argv[] )
{
if(argc<2)
{
printf("usage: %s #port\n",argv[0]);
exit(1);
}
if(signal(SIGINT,sig_handler)==SIG_ERR)
{
perror("signal sigint error");
exit(1);
}
//步骤一:创建socket
//创建在内核中;是一个结构体;
//AF_INET:ipv4
//sock_stream :tcp 协议;
sockfd=socket(AF_INET,SOCK_STREAM,0);
//步骤二:将socket和地址绑定;包括(ip。port等)
struct sockaddr_in serveraddr;
memset(&serveraddr,0,sizeof(serveraddr) );
//往地址中填入ip port internet地址足类型等
serveraddr.sin_family=AF_INET;//ipv4;
serveraddr.sin_port=htons(atoi(argv[1]));//port
serveraddr.sin_addr.s_addr=INADDR_ANY;//"192.168.0.1";//监听所有的网卡上面的客户端的链接请求;
if(bind(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0)
{
perror("bind error");
exit(1);
}
//步骤三
//调用listen 函数启动监听 制定port监听;
//通知系统去接受来自客户端的链接请求;
//及其昂接受到的客户端请求放置到对应的队列中
//第二个参数: 指定队列的长度;
if(listen(sockfd,10)<0)
{
perror("listen error");
exit(1);
}
//步骤四:
//调用 accept函数从队列之中获得一个客户端的请求链接
//并且返回一个新的socket 描述符;针对客户端的;
//如果没有客户端链接,调用这个函数会阻塞,直到获得一个客户端的链接;
struct sockaddr_in clientaddr;
socklen_t clientaddr_len=sizeof(clientaddr);
while(1)
{
int fd=accept(sockfd,(struct sockaddr*)&clientaddr,&clientaddr_len);
if(fd<0)
{
perror("accept error");
exit(1);
}
//步骤五:利用I/O函数(write/read)
//和链接的客户端进行双向的通信;
out_addr(&clientaddr);
do_service(fd);
//步骤6 关闭socket;
close(fd);
}
return 0;
}
2、客户端
/*************************************************************************
> File Name: src/time_tcp_client.c
> Author: sicaolong
> Mail: sicaolong4@163.com
> Created Time: 2018年07月18日 星期三 21时47分15秒
************************************************************************/
#include<stdio.h>
#include<sys/socket.h>
#include<stdlib.h>
#include<string.h>
#include<memory.h>
#include <string.h>
#include<unistd.h>
#include <arpa/inet.h>
//#include<>
//#include<>
//#include<>
int main(int argc,char *argv[])
{
if(argc<3)
{
printf("usage : %s ip port\n",argv[0]);
exit(1);
}
//步骤一:创建socket
int sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd<0)
{
perror("sockert error");
exit(1);
}
struct sockaddr_in serveraddr;
memset(&serveraddr,0,sizeof(serveraddr));
serveraddr.sin_family=AF_INET;
serveraddr.sin_port=htons(atoi(argv[2]));
//将ip地址转换成网络字节序 填入到serveraddr中
inet_pton(AF_INET,argv[1],&serveraddr.sin_addr.s_addr);
//步骤二:connect 链接到服务器端;
if(connect(sockfd,(struct sockaddr*)&serveraddr,sizeof(serveraddr))<0)
{
perror("connect error");
exit(1);
}
//步骤三 调用I/O函数
//和服务器断进行双向 通信;
char buffer[1024];
memset(buffer,0,sizeof(buffer));
size_t size;
if((size=read(sockfd,buffer,sizeof(buffer)))<0)
{
perror("read error");
exit(1);
}
if(write(STDOUT_FILENO,buffer,size)!=size)
{
perror("write error");
}
//步骤四 关闭套接字
close(sockfd);
return 0;
}