如何判断socket已经断开

来源:互联网 发布:微场景相册制作软件 编辑:程序博客网 时间:2024/04/29 14:31

转载注明出处:http://www.tuicool.com/articles/7RJnyu

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

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

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

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

  这是我写的一个代码!

   

int SocketConnected(int sockfd){    fd_set rfds;    int res,read_res;    char buf[20] = {'\0'};    struct timeval timeout={3,0};    int again_time = 0;    FD_ZERO(&rfds);    FD_SET(sockfd,&rfds);    res = select(sock+1,&rfds,NULL,NULL,&timeout)    if(res > 0){        read_res = recv(sockfd,buf,sizeof(buf),0);        if(read_res  < 0){            if(errno == EINTR){                printf("Interrupted by the signal!\n");                return 1;             } else {                printf("error!,the sockfd maybe closed!\n");                return 0;             }         } else if (read_res == 0){             printf("error!,the sockfd maybe closed!\n");             return 0;         } else {             printf("contenct normal!\n");             return 1;          }      } else if(res == 0){          printf("the timeout! content normal\n");          return 1;      } else if (errno == EINTR){          printf("Interrupted by the signal!\n");          return 1;      } else {          printf("select error!,try again!\n");          return 0;      }}

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

头文件 Linux/tcp.h

int SocketConnected(int sock) 

if(sock<=0
return 0
struct tcp_info info; 
int len=sizeof(info); 
getsockopt(sock, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&len); 
if((info.tcpi_state==TCP_ESTABLISHED)) //TCP_ESTABLISHED 头文件也没有搜索到,用1代替吧~

//myprintf("socket connected\n"); 
return 1

else 

//myprintf("socket disconnected\n"); 
return 0

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

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