一、概述
TCP 的发送方在规定的时间内没有收到确认就要重传已发送的分组,这种概述十分简单,但是重传时间的选择却是 TCP 最复杂的问题之一。
- 如果把超时时间设置过短,则会引起不必要的重传,使网络负荷增大。
如果把超时时间设置过长,使得网络空闲时间增大,降低传输效率。
RTT
TCP 采用一种自适应算法,它记录一个分组发出的时间,以及收到相应的确认的时间。这两个时间差就是分组的往返时间 RTT,Round Trip Time。
时刻变化
- 时间构成
- 物理链路传输时间
- 末端处理时间
- 路由器排队处理时间
- 指导 RTO
RTO
- RTO,Retransmission TimeOut,超时重传时间。
- RTO 应当略大于 RTT。
- RTO 应当更平滑。
下面讲述的算法就是为了得到合适的 RTO 的值。
下图是 TCP/IP卷一计算得到的 RTO 的值。
RTO 经典算法 RFC 793
- 平滑 RTO。
- 若 α 很接近 0 时,新的 RTT 样本影响不大,反之很接近 1 时,新的 RTT 样本影响较大,RTT 值更新较快。RFC 6298 推荐值为 0.9。越大越平滑。
- 若发生超时重传,无法选择合适的 RTT 来做样本值。
-
Karn / Partridge 算法
在 1987 年时,Karn 提供了一个算法: 在计算加权平均 RTTS 时,只要报文段重传了,就不采用其往返时间样子。这样得出的加权平均 RTTS 和 RTO 就比较准确。但还是有以下问题:
在某一时间,网络出现波动,突然变慢,产生较大延时,这个延时可能导致需要重传所有的包,于是由于忽略重传的样本时间,所以 RTO 不会被更新。
于是 Karn 算法使用一个取巧的方式: 只要一发生重传,就对现有的 RTO 值翻倍,很明显,这也不靠谱。
Jacobson / Karels 算法 RFC 6298
前面两种算法都采用 加权移动平均,这种方式对突然间的网络波动感知变化小,因为被平滑了。所以,1988年有人提供了一个新的算法 — Jacobson / Karels Algorithm。这个算法引入了最新的 RTT 采样和已平滑过的 SRTT 的差做因子进行计算。
注: 以上参数值是针对 Linux 而言。