自动检测SOCKET链接断开

如何判断SOCKET已经断开

最近在做一个服务器端程序,C/S结构。功能方面比较简单就是client端与server端建立连接,然后发送消息给server。我在server端会使用专门的线程处理一条socket连接。这就涉及到一个问题,如果socket连接断开(异常,正常)后,我如何才能感知到?server端这边是绝对被动的,sever端不能主动断开连接。也没有连接链路维持包之类的。client端发送数据的时间也是不定的。在socket连接断开后, server要能够感知到并释放资源。
 
当使用 select()函数测试一个socket是否可读时,如果select()函数返回值为1,且使用recv()函数读取的数据长度为0 时,就说明该socket已经断开。
为了更好的判定socket是否断开,我判断当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR 。如果errno == EINTR 则说明recv函数是由于程序接收到信号后返回的,socket连接还是正常的,不应close掉socket连接。

PS:对于堵塞socket的recv函数会在以下三种情况下返回:
(1)recv到数据时,会返回。
(2)在整个程序接收到信号时,返回-1。errno = EINTR。//在程序的起始阶段,屏蔽掉信号的除外。部分信号还是屏蔽不掉的。
(3)socket出现问题时,返回-1.具体错误码看 man recv()
(4)一定要看 man 说明,很详细,很有帮助。
这种方法经过长时间测试后,是有效的。所以写出来让大家参考一下,请大家发表意见。
 
 
我的方法不一样,我用getsockopt来判断,还是蛮准确的 
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)) 
{ 
//myprintf("socket connected
"); 
return 1; 
} 
else 
{ 
//myprintf("socket disconnected
"); 
return 0; 
} 
}

  

tcp_info和TCP_ESTABLISHED在linux/tcp.h
包含
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/config.h>
#include <linux/skbuff.h>
#include <linux/ip.h>
#include <net/sock.h>
 
http://www.cse.scu.edu/~dclark/am_256_graph_theory/linux_2_6_stack/globals.html#index_t

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)) 

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

else 

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

}

原文地址:https://www.cnblogs.com/wlzy/p/8696919.html