说明: 本文仅供学习交流,转载请标明出处,欢迎转载!
本文是以下文献相关内容的总结
[1] 《TCP/IP详解 卷1:协议》
[2] 《TCP/IP协议族 第4版》
[3] 《计算机网络 第5版》
TCP协议中经常会发生超时重传的情况,我们知道超时重传中的“时”是即RTO。RTO是Retransmission Time-OutD的缩写,该时间决定了发送方在发送数据后,在多长时间内如果没有收到ACK,就重置重传计时器,并重传上次发送失败的报文。那么RTO是如何计算的呢?
RTO说白了就是根据RTT(往返时延)而确定的。但是我们知道,RTT是一个不确定的数值,因为TCP以下的网络层相当负责,每个报文发送出去后的RTT不一定相同。这样就使得RTO的计算也比较难。为了给出一个比较合理的RTO,我们需要采用统计学里面的一些方法。首先我们介绍几个RTT变量,分别是:RTTm(测量RTT),RTTs(平滑RTT),RTTD(偏差RTT)。
RTTm:m可以看成measure的缩写,它是本次时间测量的RTT值,当然本次测量不能代表着一个绝对正确的值。
注意:关于测量RTTm的获取,我们可以有不同的方法。我们可以在发送端设置计时器,也可以在发送的TCP报文选项中添加时间戳选项,用于记录发送时间,接收方接到该报文后,把该发送时间从报文中复制到ACK报文发回给发送端。所以,RTTm的计算方法并不唯一。前者比后者快,因为报文比后者短。
RTTs:s是Smoothed的缩写,我们可以把RTTs看成是一个平均的RTT,相当于一个累积的RTT的期望值,它不仅考虑本次测量到的RTT值,还会吸取历史经验,考虑以前的RTT的值,且之前的RTT的值占的比重远高于本次测量的RTT(即RTTm)。所以,RTTm(本次测到的RTT)只是整体RTT的一个样本。
注意:我们可以将RTTs看成RTT的一个平均值(或期望值)
RTTD:D是Deviation(偏差)的缩写,偏差说白了就是误差值,它也是一个经验累加值。跟RTTm一样,它会将之前采用的RTTD作为一个参考,同时累加上当前的偏差。
注意:偏差我们可以看做是测量值与平均值(或期望值)之差的绝对值。所以本次RTTD=|RTTm-RTTs|。
RTO: RTO主要考虑RTT的期望值和偏差。
综上的理解,我们就可以很快理解并记住以下公式:
第一次测量时,RTTm是我们测量的结果,RTTs=RTTm,RTTD=RTTm/2
以后每次测量采用以下公式:
RTTs=(1-a)*RTTs+a*RTTm,a通常为1/8,即0.125.................................公式1
RTTD= (1-b)*RTTD+b*|RTTm-RTTs|,b通常为1/4,即0.25...........................公式2
RTO=RTTs+4RTTD....................................................................................公式3
说明:公式3不管是第一次计算还是最后一次,都是采用该公式。
FAQ:假设发送端发送一个报文后,在RTO内没有收到ACK,发送端重传该报文,并重置计时器。后来发送端收到了ACK,但是发送比较困惑的是该报文的ACK是之前发送的报文对应的ACK(可能在网络中呆了很长时间)还是本次发送的报文对应的ACK,由于这个事实不能确定,所以本次获得的RTTm是不准确的,那如何更新RTO呢?
方法一:放弃考虑本次获得的RTTm,因为我们无法测得一个准确的信息(即该ACK到底对应哪个报文),该处理方法称之为Karn算法。很明显,该算法的缺点是没有考虑本次测量值,例如,为什么会要求重传?如果不是网络不拥挤会要求重传吗?这些问题都被简单的抛弃了。
方法二:考虑到方法一的缺点和优点,通常采取的做法是:不考虑获取的RTTm,因为不确定是否正确(这是利用Karn算法的优点),同时每发生一次重传,RTO就加倍,即RTO=2*RTO(弥补了Karn算法的不足),该方法称为指数退避。
TCP协议中RTO的计算