本博客参考自《TCP/IP详解卷一:协议》
本文主要介绍TCP中的超时重传
1.往返时间RTT的计算
TCP提供可靠的运输层,其中重要的方法之一就是确认从另一端收到的数据。但数据和确认都有可能丢失。TCP通过在发送时设置一个定时器来解决这个问题。如果定时器溢出时还没有收到确认,就重传数据。
TCP超时和重传中最重要的部分是对一个给定连接的往返时间(RTT)的测量。在网络传输的过程中,这个值经常是变化的。RTT的测量必须是在同一报文的发送和确认之间。
较早的时候是通过低通滤波器来更新一个被平滑的RTT估计器来计算超时重传时间RTO(retransmission timeout)。用M表示测量的RTT,R表示被平滑的RTT估计值。
这里的一般取值0.9,
一般取值2。这种方法在RTT的变化范围很大的时候,无法跟上变化,从而引起不必要的重传。所以提出了一种新的方法。除了被平滑的RTT估计器,还需要根据RTT的方差。这种计算方法在往返时间起伏很大的时候可以得到一个较好的响应。
这里A是被平滑的RTT而D是被平滑的均值偏差。Err是刚得到的测量结果与之前的RTT估计器之差。增量g起平均作用,一般取值0.125。h是偏差的增益,一般取0.25。当RTT增大时,较大的偏差增益将使RTO快速上升。
1.1 Karn算法
在一个分组重传时会产生这样一个问题:假定一个分组被发送。当超时发生时, RTO会进行退避(增长),分组以更长的RTO进行重传,然后收到一个确认。这个确认是针对第一个或第二个分组,难以确认。这就导致重传的二义性。
Karn算法规定,当一个超时和重传发生时,在重传数据的确认最后达到之前,不能更行RTT估计器。
1.2 RTT计算举例
在这个例子中,客户端一共向服务器发送了32678字节的数据,这里只截取了一部分。

从上图中可以看出,RTT的更新只在同一报文的确认到达时才启动。TCP中内置了一个500ms的定时器,没发送一次数据时,这个定时器都会启动。在报文4时,该定时器已经在启动的状态,所以不会对报文段4进行计时,同理7,9报文段。
注意这个定时器同我们理解的定时器不同,它记录的是时钟的滴答,即只要时钟经过一个滴答定时器就加1,记录一个500ms。举例来说,在系统时钟某一滴答后的490ms,你启动了定时器。10ms后系统时钟经历一次滴答,你的定时器就会定时500ms,虽然此时真实的时间只有10ms。

上图显示了实际的RTT同系统时钟的滴答之间的关系,图中虚线表示系统时钟的滴答时刻。可以看出,RTT #1经历的时钟滴答为3,RTT #2经历的时钟滴答为1,RTT #3经历的时钟滴答为2。
下面根据RTT对RTO的值进行估计计算
①初始化A和D分别为0和3
因子2D只在初始化的时候出现,后面的计算都会以4D代替。
②同步报文超时重传,RTO指数退避
③确认报文2到达
由于估计值A一开始的值为0,所以估计器A需要被初始化。此时RTT为3个时钟滴答,所以M的值为1.5
③确认报文5到达,RTT为1个时钟滴答,M的值为0.5
④报文段10到达,RTT为2个时钟滴答,M的值为1
下图是测量的RTT和RTO的曲线

上表是确认报文2到达开始计算的。
2.拥塞避免算法
网络通信有时会达到中间路由器的极限,分组会丢失。拥塞避免是处理这种丢失分组的方法。该方法假设,分组丢失是由源主机和目的主机之间的某处网络故障造成的。有两种情况表示分组丢失:发生超时和接收到重复确认。
当拥塞发生时,为了降低分组进入网络的传输速率,需要调用慢启动算法来实现。拥塞避免和慢启动算法需要对每个连接维持两个变量一个拥塞窗口和一个慢启动门限
。这样得到的算法的工作过程如下:
1) 对一个给定的连接,初始化为1个报文段,
为6 5 5 3 5个字节。
2) TCP输出例程的输出不能超过和接收方通告窗口的大小。拥塞避免是发送方使用的流量控制,而通告窗口则是接收方进行的流量控制。前者是发送方感受到的网络拥塞的估计,而后者则与接收方在该连接上的可用缓存大小有关。
3) 当拥塞发生时(超时或收到重复确认),被设置为当前窗口大小的一半(
)和接收方通告窗口大小的最小值,但最少为 2个报文段)。此外,如果是超时引起了拥塞,则
被设置为1个报文段(这就是慢启动)。
4) 当新的数据被对方确认时,就增加,但增加的方法依赖于我们是否正在进行慢启动或拥塞避免。如果
小于或等于
,则正在进行慢启动,否则正在进行拥塞避免。慢启动一直持续到我们回到当拥塞发生时所处位置的半时候才停止(因为记录了在步骤 2中给我们制造麻烦的窗口大小的一半),然后转为执行拥塞避免。
拥塞避免算法要求每次收到一个确认时将增加为
。这样就保证理想情况下每个往返时间增加一个窗口大小。这是一种线性增长。下图展示了慢启动和拥塞避免算法的工作流程。

当=32时发送拥塞,接着
,
,这时执行慢启动算法。当
时,慢启动算法失效,每个RTT内只增加一个
。
3.快速重传和快速恢复算法
TCP的连接中,当收到3个以上的重复ACK,就认为是报文段的丢失。接下来就会重传数据报文段,无需等待超时定时器溢出。这就是快速重传算法。快速重传算法首先执行拥塞避免算法,而不是慢启动,这就是说不会变为1。算法的具体流程如下:
1) 当收到第3个重复的ACK时,将设置为当前拥塞窗口
的一半。重传丢失的报文段。设置
为
加上3倍的报文段大小。
2) 每次收到另一个重复的ACK时,增加1个报文段大小并发送 1个分组(如果新的
允许发送)。
3) 当下一个确认新数据的A C K到达时,设置为
(在第1步中设置的值)。这个ACK应该是在进行重传后的一个往返时间内对步骤 1中重传的确认。另外,这个ACK也应该是对丢失的分组和收到的第 1个重复的ACK之间的所有中间报文段的确认。这一步采用的是拥塞避免,因为当分组丢失时将当前的速率减半。
1016

被折叠的 条评论
为什么被折叠?



