何时将TCP连接视为空闲?

时间:2016-06-20 08:39:05

标签: linux sockets tcp keep-alive retransmit-timeout

我需要在任何连接上启用TCP keepalive,现在我正在努力处理测试用例的结果。我想这是因为我真的不明白第一次发送keepalive探测器的时间。我在Linux上的tcp_keepalive_time文档中阅读了以下内容:

  

发送的最后一个数据包(简单ACK不被视为数据)与第一个keepalive探测之间的间隔;之后   连接标记为需要keepalive,此计数器不使用任何   进一步

其他一些消息来源表示这是连接空闲的时间,但它们没有进一步定义这意味着什么。我还调查了史蒂文斯找到一个更正式的定义,因为我想知道“最后发送的数据包”在考虑重传时实际意味着什么。

在我的测试用例中,我有一个连接,其中数据仅以相当高的速率从服务器发送到客户端。为了测试keepalive,我们拔掉了客户端网卡上的电缆。我现在可以看到网络堆栈尝试发送数据并进入重传状态,但是没有发送保持活动探测。在重传期间不发送保持活动探测是否正确?

1 个答案:

答案 0 :(得分:15)

  

我有一个连接,数据只从服务器发送到客户端   以相当高的利率。

然后你永远不会看到Keepalive。当电线“静音”时发送Keepalive。 RFC1122对Keepalive有一些解释。

  

“保持活跃”机制定期探测a的另一端   连接当连接空闲时,即使存在   没有数据要发送

回到你的问题:

  

其他一些消息来源表示这是连接空闲的时间,   但他们没有进一步明确这意味着什么。

这是TCP在等待对手“hoy!还活着吗?”之前等待的时间。

$ cat /proc/sys/net/ipv4/tcp_keepalive_time
7200

换句话说,你一直在使用TCP连接,它一直很棒。但是,在过去的2个小时里,没有任何东西要发送。假设连接仍然存在是否合理?假设中间的所有中间盒仍然具有关于您的连接的状态,这是否合理?意见各不相同,Keepalive不属于RFC793。

  

TCP规范不包括保持活动机制   可能:(1)在瞬态期间导致完美的连接断开   互联网失败; (2)消耗不必要的带宽(“如果没有人的话   使用连接,谁在乎它是否仍然好?“)

  

为了测试keepalive,我们拔掉了客户端网卡上的电缆。

这不是测试keepalive。这是测试您的TCP重传策略,即TCP尝试传递消息的次数和频率。在Linux机器上,这(可能)最终会测试net.ipv4.tcp_retries2

  

在杀死活动TCP连接之前,如何重试次数。 RFC 1122   说限制应该超过100秒。它太小了   数。默认值15对应13-30分钟,具体取决于RTO。

RFC5482 - TCP User Timeout Option提供了更多影响它的方法。

  

TCP用户超时控制传输数据的保留时间   在强行关闭连接之前未确认。

回到问题:

  

重传期间不发送保持活动探测是否正确

这是有道理的:TCP已经尝试从另一个对等方引出响应,空的keepalive将是多余的。

特定于Linux(2.4+)options to influence keepalive

  
      
  • TCP_KEEPCNT TCP在丢弃连接之前应发送的最大keepalive探测数。

  •   
  • TCP_KEEPIDLE如果在此套接字上设置了套接字选项SO_KEEPALIVE,则在TCP开始发送keepalive探测之前连接需要保持空闲的时间(以秒为单位)

    < / LI>   
  • TCP_KEEPINTVL各个keepalive探针之间的时间(以秒为单位)

  •   

特定于Linux(2.6.37+)option to influence TCP User Timeout

  

TCP_USER_TIMEOUT最长时间   传输数据的毫秒数可能在之前未被确认   TCP将强制关闭连接。

因此,例如,您的应用程序可以使用此选项来确定在没有连接时连接存活多长时间(类似于您的NIC拔出示例)。例如。如果你有理由相信客户会回来(也许他们关闭了笔记本电脑的盖子?参差不齐的无线接入?)你可以指定12小时的超时时间,当他们确实回来时,连接仍然会起作用。