基本概念
在讲拥塞控制之前,先眼熟几个概念rwnd(接收窗口)、cwnd(拥塞窗口)、ssthresh(慢启动门限)
我们都知道,TCP是通过每次在首部设置接收窗口的大小来控制流量传输而不导致接收缓存溢出的。
而拥塞控制则是加了个拥塞窗口来维护,拥塞窗口只是个状态量,并没有在TCP首部。而TCP的发送窗口
取决与拥塞窗口和接收窗口的。发送窗口就是拥塞窗口和接收窗口的最小值。即min(rwnd,cwnd)。了解了
这么些概念后我们接着往下看。
网络拥塞的定义
当发生了超时重传或者冗余ACK的时候我们就可以认定发生了网络拥塞,这时候就需要进行拥塞控制。而正常
的收发报文段即发送端发送分组,接收方发送确定ACK分组则认为网络流程。不需要拥塞控制。
拥塞控制算法
当连接建立的时候cwnd默认值为一个报文段,ssthresh默认为65535个字节。
慢启动算法
慢启动算法的执行条件是cwnd<=ssthresh。连接刚建立cwnd = 1,进入慢启动算法。慢启动算法是当网络流通时,
即没有发生超时重传和冗余ACK重传客户端TCP每接收到一个接收段的ACK就将 cwnd x 2,就是将拥塞窗口翻倍。
当发生超时重传后将ssthresh设置为当前窗口大小的一般,即 min(cwnd,rwnd)/ 2,然后将cwnd设置为1,重新
进入慢启动。当发生冗余ACK重传报文段的时候则进入快重传快恢复阶段,快重传快恢复下面会将。还有一种情况
就是当cwnd > ssthresh的时候就认为当前网络很有可能发生拥塞,不能在那么快的提高拥塞窗口的大小了,这时候
就进入拥塞避免阶段,拥塞避免阶段也会将。
因此我们可以总结出进入慢启动算法的条件是拥塞窗口小于等于慢启动门限。而退出慢启动算法进入其他算法则是有
三种情况:1、出现了超时重传;2、出现了冗余ack;3、拥塞窗口大于慢启动门限。
拥塞控制算法
当拥塞窗口大于慢启动门限的时候就会进入拥塞控制,这时候拥塞窗口就不再采用指数增长而是进行线性增长,即每次
cwnd + 1。当出现超时重传的处理方法和慢启动出现超时重传的处理方法相同,即ssthresh = min(cwnd,rwnd) / 2
cwnd = 1。然后进入慢启动算法。当出现冗余ack的时候则进入快重传,快恢复算法。
因此进入拥塞控制的前提是:拥塞窗口大于慢启动门限。而退出拥塞控制的条件是拥塞窗口小于慢启动门限。
快重传、快恢复算法
当出现冗余ack的时候我们就可以认为ack确认的报文段的下一个报文段丢失了,我们这时候需要快速将该报文段发送给接收方,
然后将慢启动门限设置为当前窗口的一半,即ssthresh = min(cwnd,rwnd)/2,并且cwnd = ssthresh。直接进入拥塞避免。
为什么后面不将cwnd设为1进入慢启动呢,我们认为当出现冗余ack而重传下一个报文段的时候严格上不算是拥塞导致的。所以
直接进入拥塞避免。
总结
经过上述的描述我们可以对整个拥塞避免流程做个小总结
当出现超时重传和冗余ack的时候慢启动门限都要设置为当前发送窗口的一半,不同的就是超时重传还得将拥塞窗口大小设为1,重新
进入慢启动,而冗余ack则是将拥塞窗口设为慢启动门限大小并且进入拥塞避免。