SOCKET CLOSE_WAIT FIN_WAIT2 TIME_WAIT重现测试
2018-06-17 21:20:58来源:未知 阅读 ()
1 #include <iostream> 2 #include <sys/types.h> 3 #include <sys/socket.h> 4 #include <netinet/in.h> 5 #include <arpa/inet.h> 6 7 #include <unistd.h> 8 #include <errno.h> 9 #include <stdio.h> 10 #include <string.h> 11 #include <stdlib.h> 12 13 bool server(char *ip,int port){ 14 int socketfd = 0; 15 if(-1 ==(socketfd = socket(AF_INET,SOCK_STREAM,0))){ 16 printf("create socket faile,errno:%d\n",errno); 17 return false; 18 } 19 sockaddr_in serverAddr; 20 memset(&serverAddr,0,sizeof(serverAddr)); 21 serverAddr.sin_family = AF_INET; 22 serverAddr.sin_port = htons(port); 23 serverAddr.sin_addr.s_addr = inet_addr(ip); 24 if(-1==bind(socketfd,(struct sockaddr *)&serverAddr,sizeof(serverAddr))){ 25 printf("bind socket fail,errno:%d\n",errno); 26 return false; 27 } 28 if(-1==listen(socketfd,10)){ 29 printf("listen socket fail,errno:%d\n",errno); 30 return false; 31 } 32 printf("server has started...\n"); 33 int confd = 0; 34 sockaddr_in clientAddr; 35 memset(&clientAddr,0,sizeof(clientAddr)); 36 int sockLen = 0; 37 if(-1==(confd = accept(socketfd,(struct sockaddr *)&clientAddr,(socklen_t*)&sockLen))){ 38 printf("accept socket fail,errno:%d\n",errno); 39 return false; 40 } 41 int len = 0; 42 while(1){ 43 char recvBuf[64]={0}; 44 len = recv(confd,recvBuf,sizeof(recvBuf),0); 45 printf("len:%d,str:%s\n",len,recvBuf); 46 if(len ==0){ 47 printf("client shutdown socket...\n"); 48 break; 49 } 50 } 51 while(1){ 52 sleep(3); 53 } 54 return true; 55 } 56 bool client(char *ip,int port){ 57 int socketfd = 0; 58 if(-1 == (socketfd = socket(AF_INET,SOCK_STREAM,0))){ 59 printf("create socket fail,errno:%d\n",errno); 60 return false; 61 } 62 sockaddr_in serverAddr; 63 memset(&serverAddr,0,sizeof(serverAddr)); 64 serverAddr.sin_family = AF_INET; 65 serverAddr.sin_port = htons(port); 66 serverAddr.sin_addr.s_addr = inet_addr(ip); 67 68 if(-1==connect(socketfd,(struct sockaddr*)&serverAddr,sizeof(serverAddr))){ 69 printf("connect socket fail,errno:%d\n",errno); 70 return false; 71 } 72 char * sendBuf = "hello server"; 73 send(socketfd,sendBuf,strlen(sendBuf)+1,0) 74 while(1){ 75 sleep(3); 76 } 77 return true; 78 } 79 int main(int argc, char *argv[]) 80 { 81 if(argc!=4){ 82 printf("usage:CloseWaitTest [0|1] ip port. 0:server,1:client\n"); 83 return 1; 84 } 85 if(atoi(argv[1])==0){ 86 server(argv[2],atoi(argv[3])); 87 } 88 if(atoi(argv[1])==1){ 89 client(argv[2],atoi(argv[3])); 90 } 91 return 0; 92 }
测试1:进程退出的方式关闭连接。正常关闭客户端进程,服务端会收到来自于客户端的关闭请求,服务器端的连接套接字状态进入CLOSE_WAIT,由于服务器端没有主动发送关闭请求,所以客户端的套接字状态处于FIN_WAIT2
正常运行截图
服务器端的监听套接字处于LISTEN状态,服务器和客户端直接的连接套接字处于ESTABLISHED状态
ctrl+c将客户端退出
服务器端套接字处于CLOSE_WAIT状态,客户端进程套接字处于FIN_WAIT2状态,FIN_WAIT2超时后系统会回收该套接字资源,超时时间系统默认为60秒,可以通过通过 /sbin/sysctl -a | grep fin_timeout查看
由于服务器端一直没有主动关闭所以一直处于CLOSE_WAIT状态
测试2:在client函数中添加shutdown,主动关闭连接,测试结果与测试1相同
在73行与74行之间添加:
shutdown(socketfd,SHUT_WR)
测试结果与测试1相同
测试3:结合测试2,服务端收到关闭后,再发送数据给客户端,然后shutdown
在50行与51行之间添加:
char * sendBuf = "hello client"; send(confd,sendBuf,strlen(sendBuf)+1,0); sleep(10); shutdown(confd,SHUT_WR);
客户端到服务端套接字状态为TIME_WAIT,持续一分钟
close和shutdown比较
客户端调用shutdown(fd,SHUT_RDWR)时直接关闭连接,在继续接收数据时得到104异常:connection reset by peer
客户端调用close(fd)时,是减少描述符的引用计数,当计数为0时,释放描述符,而不是关闭连接,再继续接收数据时得到9异常:EBADF,无效的文件描述符
状态图
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:第四届蓝桥杯试题-马虎的算式
- 【新年呈献】高性能网络通信框架 HP-Socket v5.7.1 2020-01-07
- 套接字 2019-11-18
- 49.Qt-网络编程之QTCPSocket和QTCPServer(实现简易网络调试 2019-08-16
- c/c++ socket函数详解 2019-04-30
- socket编程为什么需要htonl(), ntohl(), ntohs(),htons() 2018-12-04
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash