Netexpert FAQ 网络分析专家学习建议入口 @netexpert成员申请指南
netexpert积分规则的说明 Netis招贤纳士(2008年11月22日更新)
发新话题
打印

SO_KEEPALIVE的相关讨论

SO_KEEPALIVE的相关讨论

12.4 SO_KEEPALIVE的相关讨论

[url]http://www.opencjk.org/~scz/network/200604201416.txt[/url]

D: microsoft

SOCK_STREAM型套接字支持SO_KEEPALIVE选项,SOCK_DGRAM型套接字不支持。缺省没
有启用保活机制。缺省超时时限是2小时,与之对应的注册表项如下:

95:

--------------------------------------------------------------------------
REGEDIT4

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\Parameters]
"KeepAliveTime"=dword:006ddd00
"KeepAliveInterval"=dword:000003e8
"MaxDataRetries"="5"
--------------------------------------------------------------------------

KeepAliveTime缺省7200000毫秒(ms),也就是两小时。KeepAliveInterval缺省1000
毫秒,也就是1秒。MaxDataRetries缺省5次。

98:

--------------------------------------------------------------------------
REGEDIT4

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\Parameters]
"KeepAliveTime"="7200000"
"KeepAliveInterval"="1000"
"MaxDataRetries"="5"
--------------------------------------------------------------------------

98上这三项都是REG_SZ型,与其它系统不同。

NT 4:

--------------------------------------------------------------------------
REGEDIT4

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"KeepAliveTime"=dword:006ddd00
"KeepAliveInterval"=dword:000003e8
"MaxDataRetries"="5"
--------------------------------------------------------------------------

2000/XP/2003:

--------------------------------------------------------------------------
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"KeepAliveTime"=dword:006ddd00
"KeepAliveInterval"=dword:000003e8
"MaxDataRetries"="5"
--------------------------------------------------------------------------

这些注册表项影响范围是整个系统。

从2000开始引入一个新的I/O控制命令SIO_KEEPALIVE_VALS,可通过WSAIoctl()针对
单个套接字设置是否启用保活机制、KeepAliveTime、KeepAliveInterval。

--------------------------------------------------------------------------
/*
* Argument structure for SIO_KEEPALIVE_VALS
*/
struct tcp_keepalive
{
    u_long  onoff;
    u_long  keepalivetime;
    u_long  keepaliveinterval;
};
--------------------------------------------------------------------------

D: scz 2002-05-13 10:40

下面是*nix系统上的相关讨论。

可以使用SO_KEEPALIVE套接口选项保持TCP连接,缺省是2小时。参看UNP 7.5小节。

--------------------------------------------------------------------------
int on  = 1;

if ( setsockopt ( s, SOL_SOCKET, SO_KEEPALIVE, &option, sizeof( on ) ) < 0 )
{
   ... ...
}
--------------------------------------------------------------------------

<<TCP/IP Illustrated Volume I>> 23.3.1小节有对此选项的进一步讨论。

这个选项通常是基于整个内核的,而不是基于单个套接字的,所以一切对它超时时限
的改变将影响本机所有设置了该选项的套接字。该选项是个乒乓开关,不能在设置该
选项时直接指定超时时限。一般各系统提供了命令行设置手段:

--------------------------------------------------------------------------
x86/Linux kernel 2.4.7-10

    /sbin/sysctl net.ipv4.tcp_keepalive_time

    或

    /proc/sys/net/ipv4/tcp_keepalive_time

x86/FreeBSD 4.5-RELEASE

    sysctl net.inet.tcp.keepidle

SPARC/Solaris 8

    ndd /dev/tcp tcp_keepalive_interval
--------------------------------------------------------------------------

UNP 7.9小节介始了TCP_KEEPALIVE选项,但它没有被广泛实现。这是Stevens十年前
说的,现在的Linux、FreeBSD和Solaris是否支持,尚未测试。我在Solaris上找到了
一个宏定义,奇怪的是,Linux和FreeBSD反是没有:

find /usr/include -type f | xargs grep TCP_KEEPALIVE | grep "#define"

/usr/include/netinet/tcp.h

#define TCP_KEEPALIVE   0x8 /* set keepalive timer  */

Linux直接操作/proc/sys/net/ipv4/tcp_keepalive_time设置超时时限。FreeBSD用
sysctl()设置。

此外UNP 21.5小节讨论了另外一些保持TCP连接的C/S模式心跳函数,但那是用户态的
实现,非TCP/IP协议栈的实现。

UNP 5.12讨论了服务进程终止时,客户端如何发觉。UNP 6.7小节给出了一个客户端
实现。更多时候关心的是,客户端不发送携带有效负载的TCP报文,如何发觉一个TCP
连接已经被服务端关闭、半关闭。

参看UNP 6.11小节和图7.5。UNP 6.3讨论了select()函数,UNP 6.10讨论了poll()函
数。

如果用select(),可以监视读满足时进行read(),如果返回值小于等于零,则认为需
要显式关闭套接字重新创建TCP连接了。对于poll()情况类似,只是初始化poll()调
用时,最好指定POLLRDNORM,而不是POLLIN。事实上这里简单调用select()或poll()
监视读满足即可,不必read(),因为客户端不发送数据,Apache是不会主动发送数据
过来的,正常时,被监视句柄应该无情况,除非FIN包或RST包到达。

有一种情况,Apache进程所在主机崩溃,服务端TCP/IP协议栈没机会发送FIN包,客
户端无法意识到发生过什么,陷入无限等待中。应该给poll()带上超时设置,超时后
显式关闭套接字重新创建TCP连接。
说了世上一无牵挂为何有悲喜
说了朋友相交如水为何重别离
说了少年笑看将来为何常回忆
说了青春一去无悔为何还哭泣

TOP

发新话题
版块跳转