我的互联网连接出现了问题,当一段时间没有使用时,它会随机“冻结”任意 TCP 连接。连接保持建立状态,但没有数据传输。
当这个情况发生时,网络状态ESTABLISHED
仍然显示本地计算机上的连接状态:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name Timer
tcp 0 53 192.168.0.10:41129 173.255.235.238:143 ESTABLISHED 8219/gnutls-cli on (79.31/13/0)
..和远程服务器:
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name Timer
tcp 0 0 173.255.235.238:143 68.5.174.98:41129 ESTABLISHED 5303/imapd off (0.00/0/0)
但是,似乎根本没有传输任何数据。如果我运行斯特拉斯在本地和远程进程中,都只显示 select 调用的重复序列(当然使用不同的 fds),例如
select(6, [0 5], NULL, NULL, {0, 50000}) = 0 (Timeout)
select(6, [0 5], NULL, NULL, {0, 50000}) = 0 (Timeout)
select(6, [0 5], NULL, NULL, {0, 50000}) = 0 (Timeout)
互联网连接总体上似乎没有受到影响,我仍然可以毫无问题地与同一服务器上的同一服务建立新连接。但是,受影响的本地应用程序似乎没有意识到这个问题,只是挂起了。
在本地端尝试传输约 10 分钟后,远程端的连接从网络状态(我无法捕捉到任何中间状态),但仍然停留ESTABLISHED
在本地端。
最后,几分钟后,本地应用程序因超时中止,并从本地 netstat 输出中消失。
当我在客户端查看此连接的数据包捕获时,发现有一段较长的(预期的)不活动期似乎触发了问题,然后本地端尝试再次传输一些数据,但从未收到 ACK。相反,发出了 15 次 TCP 重传,间隔从 0.3 秒增加到 120 秒。此后没有捕获任何活动。
有人能建议我如何进一步调试以找出问题所在以及如何解决它吗?
另外和/或作为临时的解决方法:是否有某种方法可以全局减少客户端和/或服务器上的超时时间,以减少本地应用程序中止之前的时间?
答案1
总结debian 用户线程:
这些症状与客户端和服务器之间的某些 NAT 设备一致,并且在 300 秒后断开空闲连接。
链中某处必须有一个 NAT 设备,因为客户端对其 IP 地址 (192.168.0.10) 的看法与服务器用于向客户端发送数据的 IP 地址 (68.5.174.98) 不同。此外,192.168.xy 网络保留供本地使用。
一种解决方法是启用 TCP keep-alive。不幸的是,这需要在每个程序中单独配置(例如使用ServerAliveInterval
ssh 中的选项)。然而,在 Linux 下,库keepaliveLD_PRELOAD
库可以与激活必要的套接字选项一起使用,即使对于通常不支持它的程序也是如此。
对我来说,更好的解决方案是将原先的 Cisco DPC3825 有线网关替换为 NetGear CMD31T 有线调制解调器和 NetGear WGR614v9 网关。前者也支持 NAT,但没有如此短的超时时间。