拥塞控制策略
刺猬@http://blog.csdn.net/littlehedgehog
《TCP/IP v1》中TCP的超时和重传这章讲得实在凌乱无比,再加之我们亲爱的译者同志翻译的时候也按部就班地不幸地凑齐了字数,里面很多概念看起来特别的晦涩难懂。这里我参考了《TCP/IP簇》关于TCP的相关章节,稍稍总结了下,方便我后面回头看了。
讲拥塞控制前,我们起码要知道什么叫拥塞,就像了解如何带套前,至少我们先了解什么是安全套一样。啥叫“拥塞”呢?《TCP/IP簇》曰"如果网络的负载(即是发送到网路的分组数)大于网络的容量(即网络能够处理的分组数)",打个比方说吧,就是三条高速公路的尽头汇聚到一个乡间机耕道了(高速路和机耕道中间有一个收费站,中国特色),你可以想象一下有多少的汽车在收费站面前徘徊,这就叫拥塞了!
接下来是拥塞控制,我们要解决的问题是如何尽最大努力地控制拥塞,减少拥塞。关于拥塞控制策略,《TCP/IP详解》里面直接提出的拥塞避免算法,其实这只是拥塞控制策略的一部分,先把这块内容提出来让人有种一叶障目不见泰山的感觉。拥塞控制策略是基于三部分: 慢启动,拥塞避免,拥塞检测。下面一个一个来分析下。
慢启动的原理我就不再重复打一遍字了,这里我直接拷贝一块积木的《TCP/IP 详解学习笔记》:
TCP发送方首先发送一个数据报,然后等待对方的回应,得到回应后就把这个窗口的大小加倍,然后连续发送两个数据报,等到对方回应以后,再把这个窗口加倍 (先是2的指数倍,到一定程度后就变成现行增长,这就是所谓的慢启动),发送更多的数据报,直到出现超时错误,这样,发送端就了解到了通信双方的线路承载 能力,也就确定了拥塞窗口的大小,发送方就用这个拥塞窗口的大小发送数据。要观察这个现象是非常容易的,我们一般在下载数据的时候,速度都是慢慢“冲起来 的”。
也就是说慢启动的时候,拥塞窗口大小是按照指数增长的(我们不考虑rwnd的大小限制,实际发送窗口大小是rwnd 和 cwnd 的最小值决定的),直到拥塞窗口达到一个我们设定的限制,它就不能再这样指数增长了。这段过程是我们在TCP连接初期经历的,也就是上面提到的我们用网际快车这些下载工具下载A片时经历的初期阶段,这个时候我们让拥塞窗口不停增长,这样达到一个最高的限度,这样才能保证我们能赶在今晚寝室熄灯前看到武腾兰的经典片。
拥塞避免阶段是拥塞窗口达到我们预先设定的限度之后的阶段,这个限度就是我们所说的慢启动门限,为什么会设有门限?这个问题很容易理解,因为直观上看网速肯定有个上限,当达到一定上限后,我们就不能提高了,如果再要往网络里硬塞入数据包,这就会发生拥塞现象了。这个阶段我们要保证这个拥塞窗口不再如同慢启动一样疯狂指数级增长了,所以我们的策略是当窗口里的所有报文都受到确认后,cwnd就加一个报文段,即是加一了,这样就减缓了cwnd增长。《TCP/IP 详解》说的是受到一个确认,cwnd加1/cwnd ,其实一个道理,不过玩了个数字游戏罢了。
拥塞检测阶段是发现了拥塞我们的处理办法,一旦拥塞发生了,我们必定要降低往网络里面塞数据量,这自然是通过发送方控制cwnd来达到目的了(这里我们忽略rwnd的影响),而对于发送方来说,它只是不停地发数据,根本不知道网络是否拥塞了(为什么?)。它唯一能体会到的是自己被逼重传数据包的时候,发送方要重传数据包的时候无非两种情况,一个是超时,也就是发送方前面发的数据包在规定时刻没有受到接受端的确认,这就好比你发了邮件对方不告诉你受到没有,这种情况很可能是拥塞发生了,中间路由器把包给丢了(数据严重拥塞,它直接给你丢了也不告诉你),接受方根本没有受到数据包,这样我们自然收不到确认了。所以这里处理是:
1、门限值设为当前窗口一半 2、cwnd设为一个报文段 3、重新从慢开始启动
第二种情况是受到了>=3个的ACK确认,这个是由于其中一个报文段丢了造成的,然后后面的包又没有丢失,所以每发一个数据包,接受端每收到一个,就发现咦,不对,这个不是我马上想要的,于是它就发个想要数据包的ACK,这种情况出现拥塞可能性比较小,有同学问为什么这个同样是丢包了,为什么不是拥塞呢?很简单,如果拥塞了,那中间路由器很可能会大量丢报,那我们受到ACK确认的数据包可能性也比较小,所以这里不大可能是拥塞。这里我们处理较第一种情况反应弱点儿:
1、门限值还是设为一半 2、cwnd设置为门限值 3、回到拥塞避免,而不是慢启动。
CSDN博客啊~ 越来越不争气了~~