TCP server close_wait状态处理方法

本文详细解释了TCP连接中CLOSE_WAIT状态的意义及如何处理。通过分析recv函数返回值和errno值来判断socket连接的状态,提供了非阻塞模式下连接管理的有效策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CLOSE_WAIT:这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话, 那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。


非阻塞模式,如果暂时没有数据,返回的值也会是<=0的,如果用阻塞模式的话,返回<=0的值是可以认为socket已经无效了。

当使用 select()函数测试一个socket是否可读时,如果select()函数返回值为1,
且使用recv()函数读取的数据长度为0 时,就说明该socket已经断开。


经过代码试验,如果进程受到一些信号时,例如:EINTR,recv()返回值小于等于0时,这是就需要判断 errno是否等于 EINTR , 如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。

如果write,我觉得还有一些情况需要考虑,那就是写的太快的时候,有可能buffer写满了,这是,errno是EAGAIN,可以根据实际需要,如果errno是EAGAIN的话,再写几次。

当然,read的时候也有类似write的情况,需要check一下errno,如果是EAGAIN或者EINTR,最好不要立刻终止操作,再尝试一下!

  1. int SocketConnected(int sock)   
  2. {   
  3.     int res,recvlen;  
  4.     char buf[20] = {'\0'};  
  5.     struct timeval timeout={3,0};   
  6.     fd_set rdfs;  
  7.     FD_ZERO(&rdfs);  
  8.     FD_SET(sock,&rdfs);  
  9.       
  10.     res = select(sock+1,&rdfs,NULL,NULL,&timeout);  
  11.       
  12.      if(res > 0){  
  13.   
  14.         recvlen = recv(sock,buf,sizeof(buf),0);  
  15.         if(recvlen > 0){  
  16.             printf("socket connected\n");   
  17.             return 1;  
  18.         } else if (recvlen < 0 ){  
  19.              if(errno == EINTR){  
  20.                  printf("socket connected\n");   
  21.                  return 1;  
  22.              }else {  
  23.                  printf("socket disconnected! connect again!\n");   
  24.                  return 0;  
  25.             }  
  26.         } else if (recvlen == 0){  
  27.             printf("socket disconnected!connect again\n");   
  28.             return 0;  
  29.         }   
  30.     } else if(res == 0 ){  
  31.         //time out  
  32.         printf("socket connected\n");   
  33.         return 1;  
  34.     } else if(res < 0){  
  35.         if (errno == EINTR){  
  36.            printf("socket connected\n");   
  37.            return 1;   
  38.         }else{   
  39.            printf("socket disconnected ! connect again!\n");   
  40.            return 0;  
  41.         }    
  42.     }  
  43.     return 0;  
  44. }  

参考:

http://blog.youkuaiyun.com/sjin_1314/article/details/8897588

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值