一、概述

TCP 的发送方在规定的时间内没有收到确认就要重传已发送的分组,这种概述十分简单,但是重传时间的选择却是 TCP 最复杂的问题之一。

  • 如果把超时时间设置过短,则会引起不必要的重传,使网络负荷增大。
  • 如果把超时时间设置过长,使得网络空闲时间增大,降低传输效率。

    RTT

    TCP 采用一种自适应算法,它记录一个分组发出的时间,以及收到相应的确认的时间。这两个时间差就是分组的往返时间 RTT,Round Trip Time。

  • 时刻变化

  • 时间构成
    • 物理链路传输时间
    • 末端处理时间
    • 路由器排队处理时间
  • 指导 RTO

image.png

RTO

  • RTO,Retransmission TimeOut,超时重传时间。
  • RTO 应当略大于 RTT。
  • RTO 应当更平滑。

下面讲述的算法就是为了得到合适的 RTO 的值。
下图是 TCP/IP卷一计算得到的 RTO 的值。
image.png

RTO 经典算法 RFC 793

  • 平滑 RTO。

rtt经典算法.png

  • 若 α 很接近 0 时,新的 RTT 样本影响不大,反之很接近 1 时,新的 RTT 样本影响较大,RTT 值更新较快。RFC 6298 推荐值为 0.9。越大越平滑。
  • 若发生超时重传,无法选择合适的 RTT 来做样本值。
  • 不适用于 RTT 波动大(方差大)的场景。

    Karn / Partridge 算法

    在 1987 年时,Karn 提供了一个算法: 在计算加权平均 RTTS 时,只要报文段重传了,就不采用其往返时间样子。这样得出的加权平均 RTTS 和 RTO 就比较准确。但还是有以下问题:

  • 在某一时间,网络出现波动,突然变慢,产生较大延时,这个延时可能导致需要重传所有的包,于是由于忽略重传的样本时间,所以 RTO 不会被更新。

于是 Karn 算法使用一个取巧的方式: 只要一发生重传,就对现有的 RTO 值翻倍,很明显,这也不靠谱。

Jacobson / Karels 算法 RFC 6298

前面两种算法都采用 加权移动平均,这种方式对突然间的网络波动感知变化小,因为被平滑了。所以,1988年有人提供了一个新的算法 — Jacobson / Karels Algorithm。这个算法引入了最新的 RTT 采样和已平滑过的 SRTT 的差做因子进行计算。
image.png
注: 以上参数值是针对 Linux 而言。