TCP keepAlive

简介: 路上,有朋友说到服务端异常死掉,而客户端无法感知的情况。我说可以用KEEPLIVE去增加检测,刚好,网上有一文章写得很详细。 http://space.itpub.net/25259598/viewspace-684112 在一个正常的TCP连接上,当我们用无限等待的方式调用下面的Rec...
 路上,有朋友说到服务端异常死掉,而客户端无法感知的情况。我说可以用KEEPLIVE去增加检测,刚好,网上有一文章写得很详细。

<以下是转>http://space.itpub.net/25259598/viewspace-684112

在一个正常的TCP连接上,当我们用无限等待的方式调用下面的Recv或Send的时候:

   ret=recv(s,&buf[idx],nLeft,flags);

   或

   ret=send(s,&buf[idx],nLeft,flags);

   如果TCP连接被对方正常关闭,也就是说,对方是正确地调用了closesocket(s)或者shutdown(s)的话,那么上面的Recv或Send调用就能马上返回,并且报错。这是由于closesocket(s)或者shutdown(s)有个正常的关闭过程,会告诉对方“TCP连接已经关闭,你不需要再发送或者接受消息了”。但是,如果是网线突然被拔掉,TCP连接的任何一端的机器突然断电或重启动,那么这时候正在执行Recv或Send操作的一方就会因为没有任何连接中断的通知而一直等待下去,也就是会被长时间卡住。这种情形解决的办法是启动TCP编程里的keepAlive机制。

    struct TCP_KEEPALIVE inKeepAlive = {0};
    unsigned long ulInLen = sizeof(struct TCP_KEEPALIVE);
    struct TCP_KEEPALIVE utKeepAlive = {0};
    unsigned long ulOutLen = sizeof(struct TCP_KEEPALIVE);
    unsigned long ulBytesReturn = 0;

    inKeepAlive.onoff=1;
    inKeepAlive.keepaliveinterval=5000; //单位为毫秒
    inKeepAlive.keepalivetime=1000;      //单位为毫秒
    ret=WSAIoctl(s, SIO_KEEPALIVE_VALS, (LPVOID)&inKeepAlive, ulInLen, 
                          (LPVOID)&outKeepAlive, ulOutLen, &ulBytesReturn, NULL, NULL);

   此处的keepalivetime表示的是TCP连接处于畅通时候的探测频率,一旦探测包没有返回,就以keepaliveinterval的频率发送,经过若干次的重试,如果探测包都没有返回,那么就得出结论:TCP连接已经断开,于是上面的Recv或Send调用也就能马上返回,不会无限制地卡住了。

  上图是对上面文字的说明。亮条之前,TCP处于畅通状态,KeepAlive是以1000毫秒(keepalivetime的值)的频率发送探测包,在发送到第32个探测包的时候,探测包没有返回,于是就以5000毫秒(keepalivetime的值)的频率发送探测包,重发几次后,探测包都没有返回,于是就得出结论:此TCP连接已经断开了!

 

对于Win2K/XP/2003,可以从下面的注册表项找到影响整个系统所有连接的keepalive参数:


[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]

“KeepAliveTime”=dword:006ddd00
“KeepAliveInterval”=dword:000003e8
“MaxDataRetries”=”5″

 

  对于实用程序来说,2小时的空闲时间太长。因此,我们需要手工开启Keepalive功能并设置合理的Keepalive参数。在XP和WIN2003系统上,可以针对单独的socket来设置,但是在windows 2000,不能单独设置,如果设置,那么影响是整个系统的所有socket。

 

目录
相关文章
|
网络协议 Linux 关系型数据库
TCP Keepalive HOWTO
TCP Keepalive HOWTO Fabio Busatto 2007-05-04 Revision History Revision 1.0 2007-05-04 Revised by: FB First release, reviewed by TM.
1232 0
|
网络协议 Unix 网络安全
|
网络协议 Linux Windows
TCP连接探测中的Keepalive 和心跳包
采用TCP连接的C/S模式软件,连接的双方在连接空闲状态时,如果任意一方意外崩溃、当机、网线断开或路由器故障,另一方无法得知TCP连接已经失效,除非继续在此连接上发送数据导致错误返回。很多时候,这不是我们需要的。
1407 0
|
网络协议 网络安全 C++
TCP连接探测中的Keepalive和心跳包. 关键字: tcp keepalive, 心跳, 保活
1. TCP保活的必要性 1) 很多防火墙等对于空闲socket自动关闭 2) 对于非正常断开, 服务器并不能检测到. 为了回收资源, 必须提供一种检测机制.   2. 导致TCP断连的因素 如果网络正常, socket也通过close操作来进行优雅的关闭, 那么一切完美.
1451 0
|
监控 网络协议 Windows
Delphi2010中DataSnap高级技术(4)—TCP keepAlive和KeepAliveInterval参数详解
Delphi2010中DataSnap,如果客户端异常掉线或拔掉网线,那么在服务端会留下一个TCP连接,这个连接会变成死连接(经过测试,如果windows的TCP保持连接禁用的话,三个小时该死连接还不消失)。
1336 0
|
6月前
|
机器学习/深度学习 人工智能 网络协议
TCP/IP五层(或四层)模型,IP和TCP到底在哪层?
TCP/IP五层(或四层)模型,IP和TCP到底在哪层?
100 4
|
监控 网络协议 网络架构
IP协议【图解TCP/IP(笔记九)】
IP协议【图解TCP/IP(笔记九)】
142 0