客户端:
#include "apue.h" #include <netdb.h> #include <sys/socket.h> #include <fcntl.h> int main(void){ int c_fd; struct sockaddr_in s_addr; /*linux套接字地址需转化成通用sockaddr结构地址*/ char buf[MAXLINE] = "hello server!\n"; /* (1) 建立套接字 */ if((c_fd = socket(AF_INET,SOCK_STREAM,0)) < 0) printf("socket error\n"); //初始化服务器端地址 s_addr.sin_family = AF_INET; inet_pton(AF_INET,"127.0.0.1",(void *)&s_addr.sin_addr.s_addr,INET_ADDRSTRLEN); s_addr.sin_port = htons(5000); /* (2) 请求连接服务器(在通信套接字上) */ if(connect(c_fd,(struct sockaddr *)&s_addr,sizeof(s_addr)) < 0) printf("connect error\n"); /* (3) 在该套接字上发送(接收)数据 */ if(send(c_fd,"hello server",MAXLINE,0) < 0) printf("send error\n"); if(recv(c_fd,buf,MAXLINE,0) < 0) printf("reccv error\n"); printf("server send: %s\n",buf); /* (4) 关闭套接字 */ close(c_fd); exit(0); }
服务器端:
#include "apue.h" #include <netdb.h> #include <sys/socket.h> int main(void){ int reuse = 1; struct sockaddr_in s_addr;/*linux套接字地址需转化成通用sockaddr结构地址*/ int r_fd,s_fd; char buf[MAXLINE]; /* (1)建立STREAM套接字 */ if((r_fd = socket(AF_INET,SOCK_STREAM,0)) < 0) printf("socket error\n"); /* 注意:当客户端正在和服务器端通信,此时客户端在等待接收服务器端消息。 但是服务器却退出了,尝试重启,但是根本无法重启,而是会显示“bind error”。 这是由于该地址(IP+端口号)已经被绑定到一个套接字的原因。 TCP不允许重复绑定一个地址,除非超时以后这个地址才能重新被绑定。 ---但是可以使用setsocketopt()函数设置套接字选项,使得当前与该套接字 绑定的地址可以被重复绑定 !!! */ setsockopt(r_fd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(int)); /* (2)绑定用于接收请求的套接字和服务器地址 */ s_addr.sin_family = AF_INET; s_addr.sin_addr.s_addr = htonl(INADDR_ANY); s_addr.sin_port = htons(5000); if(bind(r_fd,(struct sockaddr *)&s_addr,sizeof(s_addr)) < 0) printf("bind error\n"); /* (3)宣告服务器通信端可以接受连接请求 */ if(listen(r_fd,5) < 0) printf("listen error\n"); /* (4)等待客户连接:若accept()返回,则建立连接,返回一个新套接字(用于通信) */ for(;;){ printf("waiting for ask...\n"); fflush(stdout); //不关心客户端sockaddr地址 s_fd = accept(r_fd,NULL,NULL); /* (5)在该套接字上面读写(处理请求) */ if(recv(s_fd,buf,MAXLINE,0) < 0) printf("recv error\n"); if(send(s_fd,"OK,I have recevied your quest\n",MAXLINE,0) < 0) printf("send error\n"); if(send(s_fd,"O",1,MSG_OOB) < 0) printf("send error\n"); printf("client send: %s\n",buf); } /* (6)关闭新套接字和原始套接字 */ close(r_fd); close(s_fd); exit(0); }