TCP 的超时重传
一直以来都是看 《
TCP/IP 协议》这本书来理解 TCP 的一些概念,但发现讲解的不是很清晰(或者是翻译质量的问题)。最近读Tanenbaum 的 《计算机网络第4版》,惊喜的发现这本书对 TCP 的一些概念做了非常清晰易懂的讲解,心头的一些疑问得到了解答。现整理一下我的理解,以加深记忆。
¨ 重传定时器:TCP 必须维护一个重传定时器,以进行超时重传
¨ 问题:如何设置超时时间间隔 RTO?
时间间隔太短则可能导致大量不必要的重传;太长则导致性能下降;
¨ TCP 采用了一个高度动态的算法,来不断的调整时间间隔,这个算法就是 Jacobson 1988 算法
在此算法中, TCP
需要维护几个变量:
1
)、RTT:对往返时间的当前最佳估计值
当一个数据段被发送出去后,TCP
启动定时器,如果在定时器过期之前确认数据段回来的话,则 TCP 测量一下这次确认所花的时间 M,然后根据如下公式更新 RTT。
RTT = aRTT + (1-a)M
其中 a
是平滑因子,典型的值是 7/8
这个公式的意思就是说,旧的 RTT
占有 7/8 的权重,新的往返时间占有 1/8 的权重
2
)、D:平滑的平均偏差
有了 RTT
, 如何选择 RTO 仍然需要考量,
它的计算公式是:
D
= aD + (1-a)|RTT-M|
¨ RTO 的计算公式: RTO = RTT + 4D
这个算法简单高效,
¨ Karn 算法:
Jacobson 算法只用于处理正常的情况,但是当发生重传后,如果收到一个确认,这时候就不用这个算法来调整 RTO 值了。因为你无法判断这个确认是针对第一次传输,还是后来的重传。在这种情况下,采用 Karn 算法来调整 RTO 的值 。
Karn 算法很简单:
1)、 对于发生重传的数据段,在收到确认后,不更新 RTT
2)、在重传的时候,RTO 是倍增的,直到达到最大值的限制。如果重传超过一定的次数,TCP 连接会断开
3)、在重传并收到确认后,如果下一次的数据段没有发生重传(即一次性收到确认),则又恢复 Jacobson 算法
¨ Linux 中对应的超时重传的实现代码:
待续