Keep-alive选项在Linux上无法用于传出连接


8

有谁知道Linux是否在传出连接上支持keep-alive套接字选项?

我使用keep-alive选项建立了传出连接,但netstat --timers显示关闭(我假设计时器关闭):

tcp 0 0 localhost.localdomain:44307 172.16.0.15:2717 ESTABLISHED off (0.00/0/0)

应用了相同套接字选项的传入连接显示:

tcp 0 0 172.16.0.3:8585 localhost.localdomain:21527 ESTABLISHED keepalive (29.26/0/0)

我希望我能看到套接字选项,但是ss或lsof都不会向我显示它们。

Answers:


7

首先,您需要确保在系统上启用了TCP keepalive。您可以像这样检查默认设置:

# sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_probes net.ipv4.tcp_keepalive_intvl
net.ipv4.tcp_keepalive_time = 7200
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_intvl = 75

然后确保您在代码中正确设置了它。它看起来应该像这样:

int optval = 1;
if (setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) < 0) {
    perror("setsockopt()");
    close(s);
    exit(EXIT_FAILURE);
}

在我的系统上,当我使用上述代码在两侧设置SO_KEEPALIVE时,我看到:

tcp        0      0 127.0.0.1:48591         127.0.0.1:5555          ESTABLISHED keepalive (6958.37/0/0)
tcp        0      0 127.0.0.1:5555          127.0.0.1:48591         ESTABLISHED keepalive (6958.37/0/0)

然后,我用Wireshark验证了NOP保持连接已发送。

可以在TCP Keepalive HOWTO中找到更多详细信息。


感谢您提供的信息,但是我已经设置了这些设置,并且正在按照与您完全相同的方式进行设置,我只是没有在netstat中设置keepalive。
James Hartig

1
在这种情况下,请发布有关您的系统和源代码(或简化的测试用例)的更多信息,以便我可以尝试重现该问题,否则,此处无需进行太多调试。
aculich

@aculich是正确的,如果您在系统中设置了keepalive,则是您的应用程序没有正确使用它。我建议按照aculich的建议阅读TCP Keepalive HOWTO或发布应用程序的源代码,或者尝试执行lsof看看会发生什么
tmow 2011年

0

客户端系统设置:

sudo /sbin/sysctl -a|grep keep
net.ipv4.tcp_keepalive_time = 20
net.ipv4.tcp_keepalive_probes = 1
net.ipv4.tcp_keepalive_intvl = 1

客户保留tcpdump:

sudo /usr/sbin/tcpdump  -nn -vv -i bond0 tcp and host 10.201.126.72 and port 8001
tcpdump: listening on bond0, link-type EN10MB (Ethernet), capture size 65535 bytes

但没有任何软件包捕获,这意味着tcp_keepalive_time不起作用

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.