检查非正常断开的tcp连接

转载 2011年01月18日 16:54:00

Tcp是面向连接的,在实际应用中通常都需要检测连接是否还可用.如果不可用,可分为:


a. 连接的对端正常关闭.


b. 连接的对端非正常关闭,这包括对端设备掉电,程序崩溃,网络被中断等.这种情况是不能也无法通知对端的,所以连接会一直存在,浪费国家的资源.


tcp协议栈有个keepalive的属性,可以主动探测socket是否可用,不过这个属性的默认值很大.

Linux方法:
全局设置可更改/etc/sysctl.conf,加上:

net.ipv4.tcp_keepalive_intvl = 20
net.ipv4.tcp_keepalive_probes = 3
net.ipv4.tcp_keepalive_time = 60


在程序中设置如下:

int keepAlive = 1; // 开启keepalive属性
int keepIdle = 60; // 如该连接在60秒内没有任何数据往来,则进行探测
int keepInterval = 5; // 探测时发包的时间间隔为5 秒
int keepCount = 3; // 探测尝试的次数.如果第1次探测包就收到响应了,则后2次的不再发.

setsockopt(rs, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
setsockopt(rs, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));
setsockopt(rs, SOL_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
setsockopt(rs, SOL_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

Windows方法:

//定义结构及宏
struct TCP_KEEPALIVE {
u_longonoff;
u_longkeepalivetime;
u_longkeepaliveinterval;
} ;

#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)

//KeepAlive实现
TCP_KEEPALIVE inKeepAlive = {0}; //输入参数
unsigned long ulInLen = sizeof(TCP_KEEPALIVE);

TCP_KEEPALIVE outKeepAlive = {0}; //输出参数
unsigned long ulOutLen = sizeof(TCP_KEEPALIVE);

unsigned long ulBytesReturn = 0;

//设置socket的keep alive为5秒,并且发送次数为3次
inKeepAlive.onoff = 1;
inKeepAlive.keepaliveinterval = 5000; //两次KeepAlive探测间的时间间隔
inKeepAlive.keepalivetime = 5000; //开始首次KeepAlive探测前的TCP空闭时间

if (WSAIoctl((unsigned int)s, SIO_KEEPALIVE_VALS,
(LPVOID)&inKeepAlive, ulInLen,
(LPVOID)&outKeepAlive, ulOutLen,
&ulBytesReturn, NULL, NULL) == SOCKET_ERROR)
{

}


在程序中表现为,当tcp检测到对端socket不再可用时(不能发出探测包,或探测包没有收到ACK的响应包),select会返回socket可读,并且在recv时返回-1,同时置上errno为ETIMEDOUT

 

 

补充一个查看tcp连接状态的例子:

 

int tcp_state(int tcp_fd)
{
struct tcp_info info;
int optlen = sizeof(struct tcp_info);
if (getsockopt (tcp_fd, IPPROTO_TCP, TCP_INFO, &info, (socklen_t *)&optlen) < 0) {
printf ("getsockopt() TCP_INFO error/n"); exit (0);
}
printf ("%d/n",info.tcpi_state);
if (info.tcpi_state == TCP_ESTABLISHED) return 0; /* ESTABLISHED */
else return -1;
}

 

getsockopt的TCP层实现剖析

应用层   NAME     getsockopt - get options on sockets SYNOPSIS     #include     #include     i...
  • zhangskd
  • zhangskd
  • 2013年02月18日 11:18
  • 10163

tcp sock struct 注释分析

struct tcp_sock { /* inet_connection_sock has to be the first member of tcp_sock */ struct inet_co...

TCP端口状态说明ESTABLISHED、TIME_WAIT

TCP状态转移要点 TCP协议规定,对于已经建立的连接,网络双方要进行四次握手才能成功断开连接,如果缺少了其中某个步骤,将会使连接处于假死状态,连接本身占用的资源不 会被释放。网络服务器程序要同时管...

Tcp 连接出现大量ESTABLISHED连接

问题描述: 在不考虑系统负载、CPU、内存等情况下,netstat监控大量ESTABLISHED连接与Time_Wait连接。 # netstat -n | awk '/^tcp/ {++...

服务器中判断客户端socket断开连接的方法

下面来罗列一下判断远端已经断开的方法: 法一: 当recv()返回值小于等于0时,socket连接断开。但是还需要判断 errno是否等于 EINTR,如果errno == EINTR 则说明re...
  • God2469
  • God2469
  • 2013年04月14日 21:52
  • 31981

getsockopt的TCP层实现剖析

http://blog.csdn.net/zhangskd/article/details/8561950

自动检测SOCKET链接断开

如何判断SOCKET已经断开 最近在做一个服务器端程序,C/S结构。功能方面比较简单就是client端与server端建立连接,然后发送消息给server。我在server端会使用专门的线程处理一...
  • rethyx
  • rethyx
  • 2014年02月26日 14:52
  • 1292

关于keeplive

当服务端开启心跳,客户端开启心跳,则当客户端意外断开连接,服务端释放连接,客户端释放连接 当服务端关闭心跳,客户端开启心跳,则当客户端意外断开连接,服务端不会知道,资源不会释放。而当客户端再一次向服务...

socket之KEEPALIVE机制与原理分析

LINUX之TCP连接时间----TCP keepAlive 详解 (2011-08-11 11:07:04)转载 标签: 杂谈 分类: linux 在一个正常的TCP连接上,当我们用无限等待的方式调...
  • rethyx
  • rethyx
  • 2014年02月25日 21:54
  • 4884

tcp连接的11种状态

转自:http://liujianguangaaa.iteye.com/blog/975445
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:检查非正常断开的tcp连接
举报原因:
原因补充:

(最多只允许输入30个字)