发送端流量控制算法

2016-05-04 08:30:42   最后更新: 2016-05-04 08:57:20   访问数量:499




上一篇日志中,我们介绍了 Nagle 算法和滑动窗口协议:

Nagle 算法与滑动窗口协议

他们用来让接收方实现流量控制

 

滑动窗口协议中的通告窗口用来实现接收方的流量控制,而慢启动算法所使用的拥塞窗口则用来实现发送方的流量控制

当与另一个网络的主机建立TCP连接时,拥塞窗口被初始化为1个报文段(即另一端通告的报文段大小)

每收到一个ACK, 拥塞窗口就增加到原来报文段的 2 倍(cwnd 以字节为单位,慢启动以报文段大小为单位进行增加)

发送方取拥塞窗口与通告窗口中的最小值作为发送上限

 

上一篇日志中我们提到了带宽时延积,用来作为窗口大小设置的参考,这里我们详细介绍一下:

BDP(bit) = link_bandwidth(bps) * RTT(s)

 

如果我们将发送端与接收端之间的连接想象成一条管道,带宽描述的是管道的粗细,RTT 则描述了这个管道的长度,而 BDP 则描述了这个管道的实际容量

理想状态下,任何时刻这个管道中的 ACK 的数目总是相等的,发出报文的速度与接收报文的速度刚好像等

当管道被发送的数据填满,那么就造成了拥塞,典型的情况是发送端带宽大于接收端带宽

 

顾名思义,这个算法是为了避免 TCP 连接的拥塞而设计的,他的基本假设是一旦分组丢失,就意味着拥塞的发生,通常与慢启动一起使用,他们需要维持两个变量:拥塞窗口 cwnd 和慢启动门限 ssthresh

算法的工作过程如下:

  1. 初始时 cwnd 为 1 个报文段大小,ssthresh 为 65535 字节,由于限制发送方取拥塞窗口与通告窗口中的最小值作为发送上限,因此首次发送只能发送一个报文段
  2. 当发生超时或收到重复确认时,ssthresh 被设置为当前窗口大小(cwnd 与通告窗口大小的最小值且大于等于 2)的一半
  3. 如果发生超时则将 cwnd 重新设为 1 个报文段大小
  4. 每收到一个 ACK,cwnd 就增加到原来的 2 倍,一旦 cwnd 大于等于上次发生拥塞时 cwnd 的 1/2(即 ssthresh 的值),则停止这样指数性的增长(慢启动算法),取而代之的是每收到一个 ACK 将 cwnd 加 1 个报文段大小(拥塞避免算法)

根据上面的描述,我们可以看到 cwnd 随往返时间变化如下:

 

图中,在到达 ssthresh 所指定的 16 个报文段大小之前,cwnd 的设置呈指数增长,这段时间内(前四次发送)执行的是慢启动算法,在此之后,执行的则是拥塞避免算法

 

慢启动算法和拥塞避免算法会让数据流突然减少,如果连续收到 3 个 ACK,则意味着某个报文段丢失,此时我们并不希望用突然减少数据流的方法来缓慢的恢复和重传,这时就会使用快速恢复算法:

  1. 当发生 3 个 ACK 时,将 ssthresh 设为 cwnd 的一半,重传丢失报文段,然后将 cwnd 设置为 ssthresh + 3 个报文段大小
  2. 一旦收到确认这次重传的 ACK,则将 cwnd 设置为 ssthresh,并且开始执行拥塞避免算法

 






读书笔记      ip      tcp      龙潭书斋      tcp/ip      tcp/ip详解      窗口      慢启动      cwnd      ssthresh      拥塞窗口      时延带宽积      拥塞避免算法      快速恢复算法     


京ICP备15018585号