zoukankan      html  css  js  c++  java
  • tcpip详解笔记(18)TCP的超时与重传

     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允许进行重新分组而发送一个较大的报文段,这有助于提升性能。

  • 相关阅读:
    三种解决IE版本兼容性问题
    CSS 如何让超链接访问后和访问前的颜色不同且访问后仍保留hover和active效果
    bootstrap 笔记用法
    STL优缺点
    输出最大回文数
    将一组单词逆序输出
    排序算法
    背包问题
    二进制
    sstream
  • 原文地址:https://www.cnblogs.com/feisky/p/2735680.html
Copyright © 2011-2022 走看看