计算机网络-5-7-TCP超时重传时间的选择

超时重传时间的选择

在之前说到,TCP的发送方在规定的时间内没有收到确认就要重传已发送的报文段。这种重传的概念是很简单的,但重传时间的选择却是却是TCP最复杂的问题之一。

​由于TCP下层是互联网环境,每个IP报选择的路由并不会相同,如果把超时重传时间设置的太短,就会引起很多报文段不必要的重传,浪费网络资源;如果把超时重传时间设置的太长,会使得网络的空闲时间增大,降低了传输效率。那么运输层的超时重传时间究竟设置为多大?

TCP采用的是自适应算法,它记录一个报文发出的时间,以及收到相应的确认的时间。这两个时间差就是报文段往返时间RTT。TCP保留了RTT的一个加权平均往返时间RTTs(又称平滑的往返时间,S代表Smoothed。因为进行的是加权平均,因此得到的结果更丝滑)。每当第一次测量到RTT时间样本的时候,RTTs值就取为所测量到的RTT样本的加权平均值,每测量一次新的RTT样本值:

\(新的RTTs=(1-a) * (旧的RTTs)+a*(新的Rtts样本)\)

上式中\(0<=a<1\),如果a很接近于0,说明新的RTT样本对已有的RTT样本影响不大(RTT更新较慢);若a-接近于1,说明RTT样本对已有RTT样本影响较大(RTT更新较快),现在标准建议的a值为1/8。这种方法计算出来的RTTs比测量出的RTT值更丝滑。

显然,超时计时器设置的超时重传时间RTO(RetransmissionTimeOut)应该概略大于RTTs。标准给出RTO的计算公式:

\(RTO=RTTs+4*RTTD\)

​RTTD是RTT的偏差的加权平均值,它与RTTs和新的RTT样本差有关。标准这样计算RTTD:当第一次测量时,RTTD值取测到的RTT值得一半,在以后的测量中,则使用下式计算偏差加权平均值:

\(新的RTTD=(1-b)x(旧的RTTD值)+bx|RTTS-新的RTT样本值|\)

这里b是一个小于1的系数,推荐值为1/4。

如图 5-20 所示,发送出一个报文段,设定的重传时间到了,还没有收到确认。于是重传报文段。经过了一段时间后,收到了确认报文段。现在的问题是:如何判定此确认报文段是对先发送的报文段的确认,还是对后来重传的报文段的确认?由于重传的报文段和原来的报文段完全一样,因此源主机在收到确认后,就无法做出正确的判断,而正确的判断对确定加权平均 RTTs的值关系很大。若收到的确认是对重传报文段的确认,但却被源主机当成是对原来的报文段的确认,则这样计算出的 RTTs和超时重传时间RTO 就会偏大。若后面再发送的报文段又是经过重传后才收到确认报文段,则按此方法得出的超时重传时间 RTO 就越来越长。

image

同样,若收到的确认是对原来的报文段的确认,但被当成是对重传报文段的确认,则由此计算出的 RTTs 和 RTO 都会偏小。这就必然导致报文段过多地重传。这样就有可能使RTO 越来越短。

根据自适应算法的弊端,Karn提出了一个算法:在计算加权平均RTTS时候,只要报文段重传了,就不采用其往返时间。这样得到的RTTS和RTO就比较准确。但是Karn提出的算法也有一些弊端,那就是当报文段的时延突然增大了许多,因此在原来的超时重传时间内,并不会收到确认报文段,于是就重传报文,由于该算法又不考虑超时重传的报文段的往返时间,。这样超时重传时间就无法更新。因此我们要对Karn算法进行修正:报文段每重传一次,就把超时时间RTP增大一下,做法就是取新的重传时间为旧的重传时间2倍。当不再发生报文段的重传时,再根据公式计算出超时重传时间。

选择确认SACK

如果接收方收到的报文无差错,只是未按序号,中间号缺少一些序号的数据,那么能否只传送缺少的数据而不重传已经正确接收到的数据?答案是可以的。选择确认就是一种可行的处理方法。

TCP在接收到对方发送过来的数据字节流的序号不连续的时候,结果就形成了一些不连续的字节块(图5-21),1-1000收到了,但1001-1500并没有接收到,1501-3000收到了,但3001-3500并没有接收到,如果这些字节的的序号都在窗口内,那么接收方会先接收下这些数据,但要把这些信息转却的发送方,是发送方不要再重复发送这些已经收到的数据。

由于TCP的首部没有哪个字段能够准确的提供上述这些字块的边界信息,RFC2018规定,如果要使用选择确认SACK,那么在建立TCP连接之前,就要在TCP的首部的选项加上允许SACK的选项。

posted @ 2021-09-03 16:39  LilyFlower  阅读(694)  评论(0编辑  收藏  举报