在 TCP 中有多种计时器用于不同的目的,以下是几种主要的 TCP 计时器:
一、重传计时器(Retransmission Timer)
- 作用:
- 主要用于处理报文段丢失和确认超时的情况。当发送方发送一个数据报文段后,就会启动重传计时器。
- 如果在计时器超时之前没有收到接收方对该报文段的确认,发送方就认为该报文段丢失或损坏,然后触发重传操作。
- 工作原理:
- 发送方在发送数据时启动该计时器,并根据估算的往返时间(RTT)和一些动态调整的因子来设置计时器的时长。
- 随着网络状况的变化,RTT 会发生波动,发送方会通过一些算法(如指数加权移动平均法)来不断更新和调整 RTT 的估算值,进而调整重传计时器的时长,以适应网络的变化。
二、坚持计时器(Persistent Timer)
- 作用:
- 用于解决零窗口死锁问题。当接收方的接收缓冲区已满,它会向发送方通告一个零窗口大小,此时发送方会停止发送数据。
- 然而,接收方的缓冲区可能会在稍后有空间接收新的数据,为了让发送方能够探测到接收方窗口的变化,坚持计时器就发挥作用。
- 工作原理:
- 当发送方收到零窗口通知时,启动坚持计时器。
- 计时器周期性地触发发送方发送一个探测报文段,询问接收方的窗口大小是否已经改变。
- 这个探测报文段只有 1 字节的数据,它可以触发接收方重新通告窗口大小。如果接收方的窗口仍然为零,发送方会继续等待并重新启动坚持计时器;如果接收方有了可用的缓冲区空间,它会返回一个非零的窗口通告,发送方就可以恢复正常的数据发送。
三、保活计时器(Keepalive Timer)
- 作用:
- 用于检测一个空闲连接是否仍然有效。在一些长时间没有数据传输的连接中,可能会由于网络故障或其他原因导致某一方出现异常,而另一方无法察觉。保活计时器可以帮助检测这种情况。
- 工作原理:
- 当连接双方长时间没有数据交互时,服务器端(通常是服务器)会启动保活计时器。
- 如果在计时器超时之前仍然没有数据传输,服务器会向客户端发送一个探测报文段,查看客户端是否还存在。
- 如果客户端正常响应,连接继续保持;如果客户端没有响应,服务器会在经过一定次数的重试后,认为客户端已经出现故障或异常,然后关闭连接。
四、时间等待计时器(Time_Wait Timer)
- 作用:
- 在 TCP 连接关闭时,确保旧的报文段在网络中完全消失,防止已关闭连接的报文段对新连接造成干扰。
- 工作原理:
- 当主动关闭连接的一方(通常是客户端)发送了最后一个 ACK 确认报文后,会进入 TIME_WAIT 状态并启动时间等待计时器。
- 计时器设置一个固定的时长(通常是 2 倍的最大报文段生存时间,即 2MSL)。在这段时间内,该连接所使用的端口号不能被重新使用。
- 这样可以保证在这个时间段内,如果有延迟到达的旧报文段,它们会在计时器超时之前被丢弃,从而不会干扰新建立的连接。
重传计时器的时长是根据往返时间(RTT)来计算的,并且会随着网络状况的变化动态调整。其计算过程大致如下:
一、初始 RTT 测量与估算
- 在 TCP 连接建立初期,会通过发送一个测试报文段来测量初始的 RTT。
- 发送方记录下发送报文段的时间点 。
- 当接收到对应的确认报文时,记录下时间点 。
- 初始 RTT 就计算为 。
二、后续 RTT 的平滑处理与更新
- 指数加权移动平均(Exponential Weighted Moving Average,EWMA)算法:
- 后续的 RTT 估算不会只依赖于某一次的测量值,而是采用指数加权移动平均的方法。
- 新的 RTT 估算值 计算公式为:。
- 其中, 是上一次的 RTT 估算值, 是本次测量得到的实际 RTT 值, 是一个加权因子(通常取值在 0.1 到 0.2 之间),它决定了新测量值在估算中所占的权重。较小的 意味着更平滑的变化,对突发的网络变化不太敏感;较大的 则使估算值更快地适应网络的变化。
- 重传超时时间(RTO,Retransmission Timeout)计算:
- RTO 通常基于当前的 RTT 估算值来计算。
- 一种常见的计算方法是 。
- 是经过平滑处理后的 RTT 估算值。
- 是 RTT 的偏差估计值,初始时也可以通过测量得到,后续同样可以通过类似 EWMA 的方法进行更新,例如 ,其中 是另一个加权因子(通常也在 0.1 到 0.2 之间)。
三、根据网络状况动态调整
- 当网络状况变化时(如出现拥塞、链路质量变化等),测量得到的实际 RTT 会发生波动。
- 如果连续几次测量的 RTT 增大,说明网络可能出现拥塞或延迟增加,此时 RTO 会相应地增加,以避免过于频繁的重传。
- 如果 RTT 减小,表明网络状况改善,RTO 可以适当减小,以提高数据传输的效率,但调整幅度会受到算法的限制,以避免过于频繁的大幅调整。
例如,开始时测量得到的初始 RTT 为 100ms,假设 ,。第一次测量得到新的 RTT 为 120ms,那么:
- 新的 RTT 估算值为:。
- 假设初始偏差估计值为 10ms,新的偏差估计值为:。
- 则 RTO 可以计算为:。
随着更多的 RTT 测量值不断到来,会继续按照上述算法不断更新 RTT 估算值、偏差估计值和 RTO,以适应网络的动态变化。