在使用运行在FreeBSD上的服务器应用程序并使用TCP时,我注意到即使我的应用程序显式禁用TCP套接字上的SO_KEEPALIVE,TCP保持活动探测也会被发送。
根据RFC1122第4.2.3.6节 (TCP Keep-Alives):
“如果包含keepalive,应用程序必须能够打开或closures每个TCP连接,并且它们必须默认closures。”
我发现可调参数net.inet.tcp.always_keepalive已被启用(设置为1),禁用它将阻止keepalive探测发送。
在FreeBSD中包含这个行为的原因是什么? 据我所知,Linux和Windows没有这样的select,但是FreeBSD和Mac OS X都这样做,所以他们违反了RFC。
更具体地说,在什么情况下忽略申请的意愿是有意义的?
在我的情况下,这是一个简单的解决方法,因为我可以禁用该选项,但我想了解为什么它在那里。
这个问题表明Linux根据RFC运行。
默认情况下保持活动状态的理由如下: https : //svnweb.freebsd.org/base?view=revision&revision=47752
添加句柄来控制全局TCP keepalive,并将其作为默认开启。
尽pipe他们的名字不会让TCP会话保持活跃,但如果另一端已经离职,就会杀死它们。 对于使用NAT,dynamicIP分配或在正常运行时间上有2 ^ 32 * 10 ^ -3秒上限的客户端,会发生这种情况。
networkingstream量没有可检测到的增加,因为这个:每两个小时对于一个实时TCP连接两个最小的TCP分组。
许多服务器已经启用了Keepalive。
主机要求RFC是10岁,不知道今天InterNet的松动客户端。
无论如何,如果应用程序要求,最好closures保持活动状态,例如(在C中):
int val = 0; setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
但解决这个问题并不容易。
我认为可调旋钮应该存在,但也许最好保持closures默认情况下。
我的推理是这样的,一个应用程序开发人员可以做出这种错误的决定,最终是一个系统pipe理员,应该控制这种networking策略而不是应用程序开发人员。