如何判断socket已经断开

    

非阻塞模式,如果暂时没有数据,返回的值也会是<=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;
}

另外还有另外一种检测方法,也比较好用,但是在2.4内核在编译过程中可能有问题。

头文件 Linux/tcp.h、

 int SocketConnected(int sock)
    346 {
    347     struct tcp_info info;
    348     int len=sizeof(info);
    349     if(sock<=0){
    350         return 0;
    351     }
    352     memset(&info,0,sizeof(info));
    353     getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len);
    354     if(info.tcpi_state== 1) {
    355         printf("socket connected\n");
    356         return 1;
    357     } else {
    358         printf("socket disconnected\n");
    359         return 0;
    360     }
    361 }

另外好像也可以通过 signal(SIGPIPE,xxxxx);这个测试过程中没有成功过,可能已经被屏蔽了!


以上是总结,有问题请及时提出!

你可能感兴趣的:(如何判断socket已经断开)