6. 拥塞控制
6.1 拥塞控制的原理
(1)理想状态下:路由器R1和R2向R3提供负载不超过1000Mb/s,都能从R3发送到R4。当提供的负载超过1000Mb/s后,不能再提高了,多余的数据包将被丢弃。
(2)实际情况:网络系统的吞吐量与输入负载之间的关系不是线性的。随着提供的负载增大,网络的吞吐量增长速率逐渐减小。在网络未达到饱和时就有一部分输入分组被丢弃,当网络的吞吐量明显小于理想吞吐量就开始出现轻度拥塞现象。当负载达到某一数值时,网络的网络的吞吐量反而随提供负载的增大而下降,这时网络进入拥塞状态。直至网络吞吐量下降到零,就产生所谓的死锁。
6.2 拥塞控制方法:慢开始和拥塞避免
(1)慢开始(Slow-start)
①A和B建立TCP连接,协商参数(最大报文MSS=100字节,接收窗口rwnd=3000),假设假设B发送的每个分组100字节。为了避免网络拥堵时出现大量丢包,TCP会先感知一下网络状态,再调整发送速度。如果发送一个分组,不丢包,就可以进一步提高发送速度,这就是慢开始。等丢包以后就可以断定出现堵塞(现代通信质量很高,出错而造成重传的概念很小(远小于1%)),再放慢增速,这就是慢开始。
②刚开始发送方将拥塞窗口(cwnd)初始为100字节(由MSS有关),先发送一个分组M1,接收方收到后确认M1,然后发送收到对M1的确认。
③发送方每收到一个新报文段的确认(重传的不算)就调整发送方的cwnd为原来的2倍。于是将cwnd从100增到200,便开始发送M2和M3两个分组。同样得到了接收方的确认。
④发送方继续将cwnd从200提高到400,并发送M4~M7共4个分组。因此慢开始算法就是每经过一轮次,拥塞窗口cwnd就加倍。
(2)拥塞避免(Congestion Avoidance)
①当TCP连接初始化时,把拥塞窗口cwnd=100字节(即MSS的值),慢开始门限ssthresh初始值为1600。当cwnd<ssthresh时,使用慢开始算法。即发送方每收到一个对新报文段的确认ACK,就把拥塞窗口值加倍(指数规律增长),来增大发送分组的速率。
②当cwnd增加到超过ssthresh时。就改为拥塞避免算法。即拥塞窗口按线性规律增大,每经过一个轮次增加一个MSS(100)的大小,来降低发送速率。
③但拥塞窗口增加到2400时,网络出现拥塞。就将sstresh值变1200(即发生拥塞时cwnd的1/2)。然后cwnd重新设置为100,并执行慢开始算法。
④慢开始算法的拥塞避免存在一个问题:网络一旦出现丢包(不一定是拥塞引起的),就会马上将ssthresh降低一半,同时cwnd减小为1个MSS,并重新执行慢开始算法。这代价很大,现在一般普遍使用的是快重传和快恢复算法。
6.3 拥塞控制方法:快重传和快恢复
(1)快重传(Fast Restransmit)
①快重传算法要求接收方每收到一个失序的分组后,发送方都能及早地发现。于是就要求接收方立即重复确认(如图中M3丢弃后,会连续发送3个重复确认包M2),而不要等发送方对M3超时重传时才发现丢包。
②由于接收方收到了M1、M2并进行了确认,但不能确认M4,因为M4是收到的失序失组。于是根据快重传的规定,这时接收方会连续发出3个对M2的重复确认,以告诉发送方M3到达,要求重传。发送方接收到三个连续的对M2的重复确认,就会立即重传M3而不必等到M3的重传计时器到期。(该算法会使整个网络的吞吐量增加约20%,加大了网络的负担)。
(2)快恢复(Fast Recovery)
①当发送方连续收到三个重复确认时,就执行“乘法减小”算法。即把慢开始门限减半(为1200)。但请注意,接下来不执行慢开始算法,而是执行快恢复算法。
②发送方认为现在网络很可能没有发生拥塞,可能只是网络一些小故障。(因为如果网络发生了严重拥塞,就不会一连有好几个报文段连续到达接收方,就不会连续发送重复确认)。因此,与慢开始不同,现在它不执行慢开始算法而是执行快恢复,即cwnd不设为MSS,而是让cwnd=ssthresh=1200(即为2400的一半),然后加法线性增大。
6.4 发送窗口的上限
(1)发送方的发送窗口受拥塞控制(cwnd)和接收方的接收窗口(rwnd)大小的影响。从接收方对发送方的流量控制的角度考虑,发送方的发送窗口一定不能超过对方给出的接收窗口值。
(2)发送方窗口的上限值=min(rwnd, cwnd)。