1. 超时重传时间RTO
在前面tcp可靠传输学习中,相信大家都有体会,tcp协议之所以能保证数据到达目的地,主要有两点:一是tcp会对传输的数据进行确认,二是tcp在传输数据过程中会对丢失的数据设置一个超时计时器(超时重传时间,简称RTO
)进行超时重传。
对于超时计时器有以下几点要明白的:
1.当tcp发送了的发送窗口中的报文段时,就会启动这个计时器
2.当计时器超时后,tcp就会重传发送窗口中最前端的报文
,并重启计时器
3.如果tcp中的发送窗口没有没有数据,就停止该计时器,否则将重启计时器
2. 往返时间(RTT)
关于超时重传的时间在停止等待协议中简单提过,超时重传时间的设置是比较复杂的,超时重传时间或大或小都会影响传输效率,但可以肯定的是:超时重传时间设置要比数据报往返时间(往返时间,简称RTT)长一点
。
简单来说,往返时间(RTT)指的其实是一个数据报发送到目的地,然后到发送方收到确认需要多少时间,这就是测量RTT。我们需要记住,发送的报文段和确认的报文并非是一一对应,也有可能是多个发送的报文对应一个确认报文。
注意:在tcp中,任何时刻只能有一个正在进行的RTT测量,一旦开始RTT测量,就不能再进行其他测量。
3. 测量RTT
RTT是随着网络环境而动态变化的,也就是说每次测量RTT都可能有变化,就目前复杂的互联网环境来说,单次的测量RTT值无法被用于超时重传。因此tcp使用了一种加权平均往返时间 RTTSRTTS(又称为平滑的往返时间,这里,我们把加权平均往返时间RTTs统一简称为RTTSRTTS,S表示Smoothed,因为进行的是加权平均,因此得出的结果更为平滑)。
第一次测量
RTT时,RTTSRTTS就取所测量到的RTT样本值,即RTTS=RTT样本RTTS=RTT样本。以后每次测量
到一个新的RTT样本,就按下面的公式重新计算一次RTTSRTTS:
在上面的公式中a的取值为:0≤α≤10≤α≤1,RFC推荐的αα值为1/8,即0.125。通过上面的公式得出的加权平均往返时间RTTs就比直接测量得出的RTT更加平滑,换句话说,新RTTS新RTTS就是由7/8的旧RTTS旧RTTS和当前1/8的RTTRTT(测量的新RTT样本)相加得出的。
值得注意的是,如果αα的取值越小,那么RTTSRTTS更新相对较平稳;反之αα的值越接近于1,则RTTSRTTS更新浮动较大。
3.1 例1
根据上面的公式,来举个例子,当前RTTSRTTS = 300ms,测量到的新RTT样本为900ms,按照上面的公式来计算,新RTTS新RTTS = (1 - 0.125)x 300ms + 0.125 x 900ms,此时新RTTS新RTTS值为375ms。也就是说,这里αα的取值是比较小的,因此测量到的新RTT样本较高时,其实对新RTTS新RTTS影响不大。
3.2 例2
现在,我们再来举个例子,现在设置αα的值为0.625,当前RTTSRTTS为300ms,测量到的新RTT样本为900ms,根据上面的公式来计算,新RTTS新RTTS = (1 - 0.625)x 300ms + 0.625 x 900ms,此时新RTTS新RTTS值为675,也就是说,这里αα的取值较大,因此测量到的新RTT样本较高时,对新RTTS新RTTS影响已经是较大了。
那么现在我们知道了往返时间RTT,就可以根据往返时间RTT来设置超时重传时间了。
4. 计算RTT的偏差
这里再说一句,前面我们为了方便,统一把超时重传时间简称为RTO,加权平均往返时间简称为RTTSRTTS。
前面我们也说过,超时重传的时间设置的要比往返时间(RTT)要长一些,显然,超时计时器设置的超时重传时间(RTO)应该略大于上面公式中计算出的加权平均往返时间(RTTSRTTS),意思就是RTO要比RTTSRTTS多那么一点点时间。
问题来了,这多出来的一点点时间从哪里来呢???
实际上,上面所说的一点点时间指的是RTT的偏差,其实就是还要计算RTT的偏差,RTT的偏差用RTTDRTTD来表示。好吧,我们姑且把RTTDRTTD认为是要多计算的一点点时间,而事实上它就是这样的。
因此,超时重传时间 = 加权平均往返时间RTTs + 一点点时间 , 于是就有了下面的公式:
再次对在上面的公式解释一遍:超时重传时间 = 加权平均往返时间RTTSRTTS + 一点点时间,前面说了RTTDRTTD 是RTT的偏差,其实这有点不太准确,更为正确的说法:RTTDRTTD 是RTT的偏差的加权平均值。
RFC建议这样计算RTTDRTTD :当第一次测量
RTTDRTTD 时,RTTDRTTD 值取为测量到的RTT样本值的一半,公式为:
在以后的每次测量
RTTDRTTD中,使用下面的公式加权平均的RTTDRTTD,这样得到的就是更为平滑的RTTDRTTD:
通常ββ是一个小于1的数,RFC推荐的值为1/4,即0.25 。这里要注意的是:,第一次测量RTTDRTTD的公式中,所计算出的RTTDRTTD不是平滑的,而每次测量RTTDRTTD的公式中所计算出的才更为平滑。
实际上,RTTDRTTD 就是一个均值偏差,它就相当于某个样本到其总体平均值的距离。这就好比你的成绩与你班级平均成绩差了多少。
5. 计算超时重传时间(RTO)
这里,我们再次回到计算平滑RTTDRTTD小节中讲过的超时重传时间的计算公式,即RTO=RTTS+RTTDRTO=RTTS+RTTD公式,将其更新为RTO=RTTS+RTTD(平滑)RTO=RTTS+RTTD(平滑)
也就是说,超时重传时间(RTO)的计算是基于平滑
往返时间(RTTSRTTS)和 平滑
RTTDRTTD。那么关于超时重传时间的计算公式,RFC是这样规定的:
通过上面的公式可知,RTO的计算就是RTTs 加上当前平滑的RTTDRTTD的4倍。
5.1 通过wireshark工具计算RTO
下面再通过一个例子来说明,我们主要分析双方在tcp建立连接阶段的和发送数据报阶段。如图1所示,当本机访问111.13.100.2站点时会发出tcp连接建立请求。
1. 首先本机发送了第一个SYN报文(第57个报文)后,发送的时间为7.841689000,此时这些变量RTTRTT,RTTSRTTS ,RTTDRTTD还没有值。假设RTO的值为0.5秒,这些变量的值应该为:
RTT=?RTT=?
RTTS=?RTTS=?
RTTD=?RTTD=?
RTO=0.5RTO=0.5
第57个报文的信息如下:
2. 然后到R1收到确认报文(第58个报文),时间为7.873524000。测量出RTT样本 = 7.873524000 - 7.841689000 ,即RTT 样本 = 0.031835000,这时变量的值应该为:
RTT=0.031835000RTT=0.031835000
RTTS=0.031835000RTTS=0.031835000
RTTD=0.031835000/2=0.015917500RTTD=0.031835000/2=0.015917500
RTO=0.031835000+4×0.015917500=0.095505000RTO=0.031835000+4×0.015917500=0.095505000
第58个报文的信息如下:
大家可以根据tcp连接建立时RTO的计算过程,来进行测试计算发送数据报阶段的RTO,由于tcp连接建立的RTO是第一次计算,得到的是初始的RTO,而发送数据阶段的RTO计算得到的应该是更加平滑的RTO,这是它们之间的区别,这也是在进行计算时要注意的地方,也就是注意区分第一次RTO和平滑RTO计算方式的区别。
6. Karn算法

图4-Karn算法
考虑这么一种情况,发送方在时间点1发送了一个M1,假设发送方在超时计时器超时的范围内,即时间点2重传了M1。当发送方在时间点3收到了M1的确认时就懵了,如上图所示,此时发送方不知道这个确认M1到底是对谁的确认,产生了模糊性。
因为新的RTT值要根据报文段发送的时间来计算,如果发送方收到的确认M1是对时间点2中重传M1的确认,则当前RTT的计算必须从时间点2开始计算。如果确认M1是对时间点1的M1的确认,那么当前RTT的计算必须从时间点1开始计算。
对于上面的这种情况,tcp使用了karn算法解决了这种模糊的情况,karn的算法在计算新的RTT时,如果重传了报文,则不会使用新的RTT值,反之,没有重传就更新RTT值。
7. 指数退避
对于上面Karn算法所描述的情况,如果发生了重传,那么RTO的数值又是多少?
此时tcp会采取指数退避策略,每一次重传,RTO的数值就会加倍。因此,如果报文重传一次,就是2×RTO2×RTO,如果重传了二次,就是4×RTO4×RTO,以此类推。

图5-指数退避
如上图所示:发送方发送了M1,经过3.24秒后,超时计时器超时并对M1进行了重传,而超时计时器重启设置为6.48秒,是原来RTO的2倍。发送方在超时时间内接收到了确认M1报文,此时RTO不变,重启超时计时器。接着发送方又发送了M2报文,在超时时间内收到了M2确认报文,然后才能重新计算RTO的数值(Karn算法)。
测量RTT新样本 = 2.15s,在这里我们假设之前的旧RTTSRTTS = 1.625 ,旧RTTDRTTD = 0.78,那么根据公式计算,这些变量的值为:
RTTS=(7/8)×1.625+(1/8)×2.15=1.690625RTTS=(7/8)×1.625+(1/8)×2.15=1.690625
RTTD=(3/4)×0.78+(1/4)×|1.690625−2.15|=0.69984375RTTD=(3/4)×0.78+(1/4)×|1.690625−2.15|=0.69984375
RTO=1.690625+4×0.69984375=4.49RTO=1.690625+4×0.69984375=4.49
说明: 这一篇比较偏理论,有一些公式需要计算,大家在看的时候发现有计算错误地方还请及时指出,感谢。