zoukankan      html  css  js  c++  java
  • TCP拥塞控制研究

    一、拥塞控制的定义
    当网络中存在过多报文时,网络的性能就会下降,这种现象称为拥塞。
    分组交换网络的性能(功率、往返时间RTT、吞吐量)与负荷的关系用下图来说明


    网络中的拥塞问题必须依靠TCP层端到端控制和IP层链路控制的共同作用才能有效的解决,其中TCP的拥塞控制仍然会起主要的、基础的作用。端到端TCP拥塞控制的本质思想是通过调整发送端的发送速率来控制网络的负荷量。具体地说,TCP不断地通过加大发送的速率来对当前网络的实际承载能力进行探测,并随时准备对网络发回的拥塞信息作出响应,即迅速减小向网络中发送信息的速率,并在新的起点上继续对网络进行试探。

    二、基本概念
    1,拥塞窗口(cwnd):拥塞控制的关键参数,控制源端在拥塞情况下一次最多能发送多少数据包。
    2,接收窗口(rwnd):接收端对源端发送窗口大小所做的限制,在建立连接时由接收方通过ACK确认带给源端。
    3,慢启动阀值(ssthresh):拥塞控制中用来限制发送窗口大小的门限值,它是慢启动阶段与拥塞避免阶段的分界点,初始值设为65535 bytes 或 awnd的大小。
    4,回路响应时间(RTT):一个数据包从源端发送到接收端直至源端收到接收端R寸该数据包确认信息所经历的时间间隔。
    5,超时重传计数器(RTO):描述数据包从发送到失效的时间间隔,是源端用来判断数据报是否丢失和网络拥塞的重要参数,通常设为2RTT或SRTT。

    -发送端的发送窗口的上限值应当取为接收端窗口rwnd和拥塞窗口cwnd这两个变量中较小的一个,即应按以下公式确定:
    发送窗口的上限值=Min[rwnd,cwnd]

    当rwnd<cwnd时,是接收端的接收能力限制发送窗口的最大值。
    当cwnd<rwnd时,则是网络的拥塞限制发送窗口的最大值。

    三、TCP拥塞控制的四个阶段
    1,慢启动阶段
    2,拥塞避免阶段
    3,快速重传阶段
    4,快速恢复阶段

    1,慢启动阶段
    当连接刚建立或超时时,进入慢启动阶段
    当新建TCP连接时,拥塞窗口(cwnd)被初始化为一个数据包大小(缺省为512或536bytes)。实际发送窗口win取拥塞窗口与接收方提供的通告窗口的较小值,即win=min(cwnd,awnd),每收到一个ACK确认,就增加一个数据包发送量,这样慢启动阶段cwnd随RTT呈指数级增长(1个、2个、4个、8个…)
    优点:
    慢启动采用逐渐增大cwnd的方法,可以防止TCP在启动一个连接时向网络发送过多的数据包而造成不必要的数据丢失和网络拥塞,并且它还能够避免采用单纯的AIMD算法造成的吞吐量增加过慢的问题。
    >为了防止cwnd的无限制增长引起网络拥塞,引入一个状态变量:慢启动阀值ssthresh
    当cwnd<ssthresh时,使用上述的慢启动算法cwnd随RTT呈指数增长。
    当cwnd>ssthresh时,使用下面的拥塞避免算法,减缓cwnd的增长速度。

    2,拥塞避免阶段
    当TCP源端发现超时或收到3个相同的ACK确认帧时,即认为网络将发生拥塞,此时进入拥塞避免阶段。
    在拥塞避免阶段,慢启动阀值ssthresh将被设置为当前cwnd的一半,当发生超时时,cwnd被置为初始值1。此时,如果cwnd<ssthresh,TCP重新进入慢启动过程;如果cwnd>=ssthresh,则执行拥塞避免算法,即cwnd在每次收到一个ACK确认时只增加1/cwnd个数据包。拥塞避免阶段cwnd随RTT呈线性增长。

    算法描述如下:
    初始化:cwnd=1
            ssthresh=65535bytes
            win=min(cwnd,awnd)
    当新的ACK确认到达时,执行以下算法:
    for every arrived packets
     if cwnd<ssthresh
    cwnd+=1; 慢启动
    else cwnd+=SMSS*SMSS/cwnd; 拥塞避免阶段
    当检测到丢包时,发送方执行以下操作:
    ssthresh=max[min(cwnd/2,awin),2];
    如果检测到定时器超时,cwnd=1;
    其中SMSS是发送方的最大报文段长度。

    从以上算法看出:在拥塞避免阶段,当数据超时时,cwnd被置为1,重新进入慢避动阶段,这会导致过大地减小发送窗口尺寸,降低TCP连接的吞吐量。因此,引入了快速重传和快速恢复机制。

    3,快速重传阶段
    当网络发生拥塞时,如果源端等待超时之后再进行拥塞控制,那么从出现拥塞到实施控制有一定的时延。除了超时之外,源端还可以使用重复ACK作为拥塞信号。源端在接收到重复ACK时并不能确定是由于分组丢失还是分组乱序产生的,通常假定如果是分组乱序,在目的端处理之前源端只可能收到一个或两个重复的ACK;如果源端连续接收到三个或更多的重复ACK,表明网络中某处已经发生了拥塞,这时,源端不等到重传定时器超时就重发这个可能丢失的分组,这就是快速重传算法。

    在快速重传阶段,当源端收到3个或3个以上重复的ACK时,就判定数据包丢失,同时ssthresh设置为当前cwnd的一半,并重传丢失的包,进入快速恢复阶段。

    4,快速恢复阶段
    当快速重传算法重传了可能丢失的分组之后,如果TCP重新进入慢启动阶段,将会使拥塞窗口减为1,重新开始探测网络带宽,从而严重影响网络吞吐量,因此快速恢复算法在快速重传之后转去执行拥塞避免算法,避免了过大地减小发送窗口而导致的网络性能下降。
    在快速恢复阶段,每收到重复的ACK,则cwnd加1;收到非重复ACK时,置cwnd=ssthresh,转入拥塞避免阶段;如果发生超时重传,则置ssthresh为当前cwnd的一半,cwnd=1,重新进入慢启动阶段。

    算法描述如下:
    step 1:
    if (dupacks=3){
    ssthresh=max(2,cwnd/2);
    cwnd=ssthresh+3*segsize;
    }
    step 2:重传丢失的分组
    step 3:此后每收到一个重复的ACK确认时cwnd=cwnd+1
    step 4:当收到对新发送数据的ACK确认时,cwnd=ssthresh,这个ACK能够对那些在丢失的分组之后,第一个重复ACK之前发送的所有包进行确认
  • 相关阅读:
    Java数据结构与算法(24)
    urllib2使用总结
    Python常见文件操作的函数示例
    Java数据结构与算法(23)
    python代码风格检查工具──pylint
    Python抓取框架:Scrapy的架构
    Java数据结构与算法(22)
    【codeforces 431D】Random Task
    【codeforces 449C】Jzzhu and Apples
    【codeforces 20B】Equation
  • 原文地址:https://www.cnblogs.com/cyrusxx/p/12824047.html
Copyright © 2011-2022 走看看