网络基本功:http报文及TCP拥塞控制机制( 四 )


期具体ssthresh的用法如下:

  • 当cwnd<ssthresh时 , 使用慢开始算法 。
  • 当cwnd>ssthresh时 , 改用拥塞避免算法 。
  • 当cwnd=ssthresh时 , 慢开始与拥塞避免算法任意 。
注意:如果当前的cwnd达到慢启动的阈值 , 则试探性的发送一个segment , 如果服务器没有响应 , TCP认为网络能力下降 , 必须降低慢启动阈值 , 同时为了避免形式继续恶化 , 有可能将窗口降低为1
4.3、快速重传(Fast Retransmit)正常情况下 , 按照上一节讲的消息重传是等到定时器超时(RTO)后在重传 , 但有时候不需要等那么久也可以重传 。比如客户端向服务器发送了5个段数据包 。第三个丢失 , 其他正常 , 那么客户端会收到3个包2的ACK , 而4、5正常到达后会被服务器缓存起来但是不会发送相应包的ACK , 因为TCP是基于积累确认机制 , 以确保丢失的包能被重发 , 数据接收准确 , ACK必须是连续的 。这个时候就不必在等待RTO的超时时间了 , 服务器判断已经丢失了就可以马上快速重传 , 提高效率 。
快速重传算法规定 , 发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文文件 , 而不必继续等待设置重传计时器时间到期 。
4.4、快速恢复(Fast Recovery)其实快速恢复并不是单独存在的 , 它是快速重传的后续处理 。通常认为客户端接收到3个ACK后 , 就会开始快速重传 , 但是如果还有更多的重复ACK呢 , 这个时候就是快速恢复要做的 。
a、当发送方连续收到三个重复确认时 , 就执行“乘法减小”算法 , 把ssthresh门限减半(也即cwnd=ssthresh/2).但是接下去并不执行慢开始算法;
b、考虑到此时能连续收到3个ACK , 说明网络没有拥塞 , 执行加法原则 , 有几个ACK就加几个段的字节数 ,  或者可以将cwnd=ssthresh , 直接进入拥塞避免算法 。
四种算法相互间的合作运行图如下所示:
网络基本功:http报文及TCP拥塞控制机制

文章插图
 
问题思考问题一:如何检测拥塞?
首先来看一下TCP是如何确定网络进入拥塞的 , TCP认为网络拥塞的主要依据是它重传了一个报文段 。上面提到过 , TCP对每一个报文段都有一个定时器 , 称为重传定时器(RTO) , 当RTO超时且还没有得到数据确认 , 那么TCP就会对该报文段进行重传 , 当发生超时时 , 那么出现拥塞的可能性就很大 , 某个报文段可能在网络中某处丢失 , 并且后续的报文段也没有了消息 , 在这种情况下 , TCP反应比较“强烈”:
  • (1)把ssthresh降低为cwnd值的一半;
  • (2)把cwnd重新设置为1;
  • (3)重新进入慢启动过程;
可以看出 , 从整体上讲 , TCP拥塞控制窗口变化的原则是: AIMD(Additive Increase Multiplicative Decrease) 。TCP/IP模型中 , 属于运输层 , 即:加性增 , 乘性减 ,  或者叫做“和式增加 , 积式减少” 。该原则很好地保证了流之间的公平性 , 因为一旦出现丢包 , 那么立即减半退避 , 可以给其他新建的流留有足够的空间 , 从而保证整个的公平性 。
问题二:为什么客户端没接收到一个ACK , 会把cwnd增加一个segment呢?
这是基于管道模型的“数据包守恒”原则 , 及同一时刻在网络中传输的数据包数量是恒定的 , 只有当“旧”数据包离开网路后 , 才能发送“新”数据包进入网络 。如果发送方收到一个ACK , 则认为有一个数据已经离开了网络 , 于是将拥塞窗口+1 , 如果网路能够严格遵守该“数据包守恒”原则 , 则拥塞的法神会大大减少 。
有趣的联想: TCP拥塞的解决就像是我们生活中的交通堵车?
其中有两个原则:
一、拥塞不可避免 , 单纯增加资源并不能避免拥塞的发生;
二、数据包守恒原则 。如果政府只是花资金修路 , 拓宽公路 , 并不能避免堵车 , 因为车的数量是不定的 , 旅游季可能有很多 , 也许一时间段没有车 , 这时候只能从源头控制 。对车流量进行控制:例如限制车辆进入主公路 , 根据实际的情况 , 如果某一时间段车辆少 , 则可以慢慢增加车辆进入该公路段 , 但是当达到一个 阈值 , 就要放缓车辆进入的速度 , 并实时地探测整条路的状况 , 如果情况紧急 , 则立刻将车流量减少一半 , 将车流量降到最低 , 然后在重新回到慢启动转态 。使整条公路能够保持畅通 , 达到最大的运行效率 。


推荐阅读