若网络中对某一资源的需求超出了其传输能力,就会发生网络拥塞,使得网络性能下降。如果出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降。下图为吞吐量比较图,网络负载是存在上限的,此时网络资源会被丢弃,吞吐量达到最大值,通常转发节点缓存不够大造成分组的丢失是网络拥塞的征兆。
---------------------------------------------------------------------------------------
TCP四种拥塞控制算法
1、慢开始;2、拥塞避免;3、快速重传;4、快速恢复
设定:1、数据为单方向发送,接收端只发送确认
2、接受端缓存足够大,即发送端发送窗口大小只由网络拥塞程度决定
3、TCP报文段作为单位。
- 发送端维护拥塞窗口cwnd,大小动态变化,由网络拥塞程度决定。网络无拥塞现象则扩大该窗口;出现拥塞则减小窗口。是否拥塞由是否及时收到确认报文决定。
- 发送端发送窗口与拥塞窗口大小一致
- 设慢开始阈值ssthresh状态变量,存在以下状态描述:
1、cwnd < ssthresh,使用慢开始算法
2、cwnd > ssthresh,停止慢开始,改用拥塞控制算法
3、cwnd = ssthresh,慢开始与拥塞控制都可以使用,二者取其一
---------------------------------------------------------------------------------------
慢开始
假设当前发送方拥塞窗口cwnd的值为1,而发送窗口swnd等于拥塞窗口cwnd,因此发送方当前只能发送一个数据报文段(拥塞窗口cwnd的值是几,就能发送几个数据报文段),接收方收到该数据报文段后,给发送方回复一个确认报文段,发送方收到该确认报文后,将拥塞窗口的值变为2。即收到多少确认报文就增加多少。所以拥塞窗口是以指数型增长的。一直到cwnd等于ssthresh阈值时启动拥塞控制算法。如下图,慢开始增长速度并不慢,只是开始时向网络注入数据报文较少。
---------------------------------------------------------------------------------------
拥塞避免
进入拥塞避免阶段时,cwnd每次只能加1。当出现报文丢失时,丢失的报文的重传计时器超时后会被判断出现拥塞,此时需要更改cwnd和ssthresh。规则如下:1、ssthresh更新为出现拥塞时cwnd数值的一半;2、cwnd赋值为1;3、重新执行慢开始算法。
如下图所示,初始ssthresh为16,当cwnd小于ssthresh成指数型增长,当cwnd > ssthresh时,cwnd逐次增加1。当其值为24时,出现丢包,此时判断为拥塞,将ssthresh调整为出现拥塞时的一般,即12。之后cwnd赋值为1,重新执行慢开始算法。由下图仍可见,拥塞避免并不是完全避免拥塞,而是将拥塞窗口的增长变为线性的,使网络不容易出现拥塞。
---------------------------------------------------------------------------------------
以上的两个算法存在不足之处,当个别报文在网络中丢失时,可能实际上网络并未发生拥塞。这将导致发送端超时重传,并误以为网络发送拥塞。由于每次拥塞控制都会将cwnd设置为1,这严重降低了传输效率。由此,新增了快速重传算法和快速恢复算法。
---------------------------------------------------------------------------------------
快速重传算法
发送端每次发送数据报文,接收端都会返回确认报文,此报文是其想接受的数据报文序号的前一位。当发生报文丢失时,接收端会一直发送乱序之前的确认报文。比如3号数据报文丢失,则接收端会一直发送2号数据报文的确认报文。而发送端不会立即重传,而是接着发4,5,6数据报文。当发完6号数据报文时,发送端会连续三次接收到2号数据报文的确认报文。此时发送端会立即重传3号数据报文,接收端接收后,会立即发送6号数据确认报文。因为4,5,6号数据报文是一直存在接收端的缓存中。这样就避免了超时重传,提高了效率。主要机制如下图所示。
---------------------------------------------------------------------------------------
快速恢复算法
如下,发送端连续接收端三个确认报文后可以确认只是丢失了个别报文(确认报文可以传回,网络没有拥塞),此时不需要启动慢开始算法。此时将ssthresh和cwnd赋值为此时的cwnd的一半,然后执行拥塞避免算法。具体机制如下图所示。
当然也有的快速回复算法,将cwnd的值增大3,即cwnd = ssthresh + 3(ssthresh为连续三次受到确认号时的cwnd值的一半)。因为接收端缓存中已经存在了三个数据报文,这三个报文不会再占用网络资源,所以拥塞窗口可以适当增大。这么做也是为了尽可能提高吞吐量。