博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TCP KEEPALIVE详解
阅读量:4107 次
发布时间:2019-05-25

本文共 1607 字,大约阅读时间需要 5 分钟。

[原文地址]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()或者shutdown()有个正常的关闭过程,会告诉对方“TCP连接已经关闭,你不需要再发送或者接受消息了”。但是,如果是网线突然被拔掉,TCP连接的任何一端的机器突然断电或重启动,那么这时候正在执行recv或send操作的一方就会因为没有任何连接中断的通知而一直等待下去,也就是会被长时间卡住。这种情形解决的办法是启动TCP编程里的keepAlive机制。

    #include “mstcpip.h”

    tcp_keepalive inKeepAlive = {0};

    unsigned long ulInLen = sizeof(tcp_keepalive);
    tcp_keepalive utKeepAlive = {0};
    unsigned long ulOutLen = sizeof(tcp_keepalive);
    unsigned long ulBytesReturn = 0;

    int ret;

    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调用也就能马上返回,不会无限制地卡住了。

图 1 Wireshark Keep-Alive抓包

 

上图是对上面文字的说明。被选中的包(第32行)之前,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。

 

转载地址:http://fttsi.baihongyu.com/

你可能感兴趣的文章
项目中的jackson与json-lib使用比较
查看>>
Jackson Tree Model Example
查看>>
j2ee-验证码
查看>>
日志框架logj的使用
查看>>
js-高德地图规划路线
查看>>
常用js收集
查看>>
mydata97的日期控件
查看>>
如何防止sql注入
查看>>
maven多工程构建与打包
查看>>
springmvc传值
查看>>
Java 集合学习一 HashSet
查看>>
在Eclipse中查看Android源码
查看>>
Android-Socket登录实例
查看>>
Android使用webservice客户端实例
查看>>
层在页面中的定位
查看>>
[转]C语言printf
查看>>
C 语言 学习---获取文本框内容及字符串拼接
查看>>
C 语言学习 --设置文本框内容及进制转换
查看>>
C 语言 学习---判断文本框取得的数是否是整数
查看>>
C 语言 学习---ComboBox相关、简单计算器
查看>>