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,最好不要立刻终止操作,再尝试一下!
- int SocketConnected(int sock)
- {
- int res,recvlen;
- char buf[20] = {'\0'};
- struct timeval timeout={3,0};
- fd_set rdfs;
- FD_ZERO(&rdfs);
- FD_SET(sock,&rdfs);
- res = select(sock+1,&rdfs,NULL,NULL,&timeout);
- if(res > 0){
- recvlen = recv(sock,buf,sizeof(buf),0);
- if(recvlen > 0){
- printf("socket connected\n");
- return 1;
- } else if (recvlen < 0 ){
- if(errno == EINTR){
- printf("socket connected\n");
- return 1;
- }else {
- printf("socket disconnected! connect again!\n");
- return 0;
- }
- } else if (recvlen == 0){
- printf("socket disconnected!connect again\n");
- return 0;
- }
- } else if(res == 0 ){
- //time out
- printf("socket connected\n");
- return 1;
- } else if(res < 0){
- if (errno == EINTR){
- printf("socket connected\n");
- return 1;
- }else{
- printf("socket disconnected ! connect again!\n");
- return 0;
- }
- }
- return 0;
- }
参考:
http://blog.youkuaiyun.com/sjin_1314/article/details/8897588