![Linux 上的“保持连接”选项不适用于传出连接](https://linux22.com/image/569533/Linux%20%E4%B8%8A%E7%9A%84%E2%80%9C%E4%BF%9D%E6%8C%81%E8%BF%9E%E6%8E%A5%E2%80%9D%E9%80%89%E9%A1%B9%E4%B8%8D%E9%80%82%E7%94%A8%E4%BA%8E%E4%BC%A0%E5%87%BA%E8%BF%9E%E6%8E%A5.png)
有谁知道 Linux 是否支持传出连接上的保持活动套接字选项?
我建立了一个带有保持活动选项的传出连接,但 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 都没有显示它们。
答案1
首先,您需要确保您的系统上已启用 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 验证了 keepaliveNOP
已被发送。
更多详情请参阅TCP 保活方法。
答案2
客户端 sysctl 设置:
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不起作用