我打开一个TCP套接字,并将其连接到网络其他地方的另一个套接字。然后,我可以成功发送和接收数据。我有一个计时器每秒发送某些东西。
然后,我通过强行失去连接(在这种情况下拉出以太网电缆)来粗鲁地打断连接。我的插座仍报告说它每秒都成功地编写数据。这持续了大约1小时和30分钟,最终给出了写入错误。指定插座最终接受另一端的暂停的内容消失了?是OS(Ubuntu 11.04),是来自TCP/IP规范的OS,还是套接字配置选项?
拉动网络电缆不会破坏TCP连接(1),尽管它会破坏通信。您可以将电缆插入并建立IP连接后,所有BackDATA都将移动。这就是使TCP可靠的原因,即使在蜂窝网络上也是如此。
当TCP发送数据时,它预计会有ACK回复。如果没有时间在一段时间内,它将重新传输数据并再次等待。在传输之间等待的时间通常会成倍增加。
在没有ACK的一定数量的重传或一定数量的总时间后,TCP将考虑连接"破裂"。多少次或多长时间取决于您的操作系统及其配置,但通常会在数分钟的顺序上删除。
来自Linux的TCP.7 Man Page:
tcp_retries2 (integer; default: 15; since Linux 2.2)
The maximum number of times a TCP packet is retransmitted in
established state before giving up. The default value is 15, which
corresponds to a duration of approximately between 13 to 30 minutes,
depending on the retransmission timeout. The RFC 1122 specified
minimum limit of 100 seconds is typically deemed too short.
这可能是您要调整的值,以更改检测连接是否消失需要多长时间。
(1)有例外。操作系统注意到被卸下的电缆后,可以通知上层,所有连接都应被视为"损坏"。
如果需要快速套接字错误传播到您的应用程序代码,您可能想尝试此套接字选项:
tcp_user_timeout (由于Linux 2.6.37) 此选项将 unsigned int 作为参数。当。。。的时候 值大于0,它指定的最大量 在毫秒中的时间传输数据可能会保留 在TCP之前未被认可 相应的连接并返回 etimedout 应用。如果将选项值指定为0,则TCP将 使用系统默认。
请参阅Linux/Man/TCP(7)上的完整描述。此选项比 tcp_retries2 编辑更灵活(您可以在创建套接字之后即时设置它)可能会进入所谓的半闭合状态。
两个出色的答案在这里和这里。
TCP用户超时可能适用于您的情况:TCP用户超时控制在连接强制关闭连接之前,传输数据可能仍未确定。
有3个依赖性TCP超时参数。在Linux上默认值为:tcp_keepalive_time默认7200秒
tcp_keepalive_probes默认9
tcp_keepalive_intvl默认75秒
总超时时间是tcp_keepalive_time (tcp_keepalive_probes * tcp_keepalive_intvl),使用这些默认值7200 (9 * 75)= 7875 secs
在Linux上设置这些参数:
sysctl -w net.ipv4.tcp_keepalive_time = 1800 net.ipv4.tcp_keepalive_probes = 3 net.ipv4.ipv4.tcp_keepalive_intvl = 20