feisky

云计算、虚拟化与Linux技术笔记
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

tcpip详解笔记(18)TCP的超时与重传

Posted on 2012-10-23 20:28  feisky  阅读(2543)  评论(0编辑  收藏  举报

 1. 对每个连接,TCP管理4个定时器:

(1)重传定时器:用于等待另一端的确认;
(2)persist定时器:用于使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口;
(3)keepalive定时器:用于检测空闲连接的另一端是否崩溃或重启;
(4)2MSL定时器:用于测量一个处于TIME_WAIT状态连接的时间

2. 超时与重传递时间间隔

超时时间可以应用程序设置(SO_RCVTIMEO,SO_SNDTIMEO),而重试的时间采用指数退避的方式,即每次重试的时间间隔为上次的2倍。在目前的实现中,首次分组传输与复位信号传输的时间间隔为9分钟。

3. 往返时间RTT的测量

平滑的RTT估计器:R=alpha*R+(1-alpha)*M,其中alpha=0.9, M是ACK测量到的RTT

重传超时时间的计算:

最初RTO=R*beta, beta=2,但该方法在RTT变化很大时会引起不必要的重传

使用均值和方差来计算RTO:

Err=M-A
A=A+gErr
D=D+h*(|Err|-D)
RTO=A+4D
其中,
A和D分别被初始化为0和3,RTO初始化为A+2D=6
只有数据报文段才会被计时,不对单纯的ACK计时

4. 重传的多义性问题(Karn算法)

当一个超时和重传发生时,在重传数据的确认最后到达之前不能更新RTT估计器,因为我们不知道ACK对应哪次传输。并且,由于数据重传,RTO已经得到一个指数退避,下次传输的时候使用这个退避后的RTO。对一个没有被重传的报文段而言,除非收到了一个确认,否则不计算新的RTO。

5. 拥塞避免算法

慢启动算法是在一个连接上发起数据流的方法,但有时分组回达到中间路由的极限。拥塞避免算法是一种处理丢失分组的方法。该算法假设分组由于损坏引起的丢失是非常少的,因此分组丢失就意味着源主机和目的主机的某处网络发生了拥塞。

有两种分组丢失的指示:发生超时、接收到重复的确认。

拥塞避免算法通常与慢启动算法同时实现,它们需要对每个连接维护两个变量:拥塞窗口cwnd和慢启动门限ssthresh。这样,算法的过程如下:
1) 对一个给定的连接,初始化cwnd为1个报文段,ssthresh为65535个字节。
2) TCP输出例程的输出不能超过 cwnd和接收方通告窗口的大小。拥塞避免是发送方使用的流量控制,而通告窗口则是接收方进行的流量控制。前者是发送方感受到的网络拥塞的估计,而后者则与接收方在该连接上的可用缓存大小有关。
3) 当拥塞发生时(超时或收到重复确认),ssthresh被设置为当前窗口大小的一半( c w n d和接收方通告窗口大小的最小值,但最少为 2个报文段)。此外,如果是超时引起了拥塞,则cwnd被设置为1个报文段(这就是慢启动)。
4) 当新的数据被对方确认时,就增加cwnd,但增加的方法依赖于我们是否正在进行慢启动或拥塞避免。如果 cwnd小于或等于ssthresh,则正在进行慢启动,否则正在进行拥塞避免。启动一直持续到我们回到当拥塞发生时所处位置的半时候才停止(因为我们记录了在步骤 2中给我们制造麻烦的窗口大小的一半),然后转为执行拥塞避免。

慢启动算法初始设置 cwnd为1个报文段,此后每收到一个确认就加 1。这会使窗口按指数方式增长:发送1个报文段,然后是2个,接着是4个……。

拥塞避免算法要求每次收到一个确认时将 cwnd增加1 /cwnd。与慢启动的指数增加比起来,这是一种加性增长(additive increase)。我们希望在一个往返时间内最多为cwnd增加1个报文段(不管在这个RT T中收到了多少个ACK),然而慢启动将根据这个往返时间中所收到的确认的个数增加cwnd。

术语“慢启动”并不完全正确。它只是采用了比引起拥塞更慢些的分组传输速率,但在慢启动期间进入网络的分组数增加的速率仍然是在增加的。只有在达到ssthresh拥塞避免算法起作用时,这种增加的速率才会慢下来。

一个示例图:

6. 快速重传算法

拥塞避免算法的修改建议1 9 9 0年提出 [Jacobson 1990b]。
在介绍修改之前,我们认识到在收到一个失序的报文段时, TCP立即需要产生一个ACK(一个重复的ACK)。这个重复的ACK不应该被迟延。该重复的ACK的目的在于让对方知道收到一个失序的报文段,并告诉对方自己希望收到的序号。
由于我们不知道一个重复的ACK是由一个丢失的报文段引起的,还是由于仅仅出现了几个报文段的重新排序,因此我们等待少量重复的ACK到来。假如这只是一些报文段的重新排序,则在重新排序的报文段被处理并产生一个新的ACK之前,只可能产生1 ~ 2个重复的ACK。
如果一连串收到3个或3个以上的重复ACK,就非常可能是一个报文段丢失了。于是我们就重传丢失的数据报文段,而无需等待超时定时器溢出。这就是快速重传算法。接下来执行的不是慢启动算法而是拥塞避免算法。这就是快速恢复算法。

7. TCP连接对ICMP差错的处理

(1)ICMP源站抑制差错:将拥塞窗口cwnd设为1个报文段大小发起慢启动,但是慢启动门限ssthresh没有变化;
(2)主机不可达或网络不可达差错:忽略,因为这两个差错通常被认为是暂时的。

8. 重新分组

当tcp重传的时候,不一定要重新传输相同的报文段。实际上,TCP允许进行重新分组而发送一个较大的报文段,这有助于提升性能。

无觅相关文章插件,快速提升流量