3.7 TCP拥塞控制
在3.5.5流量控制中有,接收方通过维护一个rwnd来控制流量,本节中考虑三个问题:
第一, 一个TCP发送方如何限制它向其他连接发送流量的速率。
第二, 一个TCP发送方如何感知从发送方到目的方产生了拥塞。
第三, 当发送方感知到拥塞,采取什么算法来改变发送速率。
第一个问题,一个TCP发送方如何限制它向其他连接发送流量的速率?
TCP连接每一端都由一个发送缓存,接收缓存和几个变量组成(这些在TCP连接的时候分配的),在发送方TCP拥塞控制机制跟踪一个额外的变量,拥塞控制窗口(cwnd),它对发送方能向网络中发送流量的速率进行了限制:
LastByteSent – LastByteAcked <= min { cwnd, rwnd};
上式左边表示是的未确认量,这个很容易理解,未被确认的就是还在传输过程中,或者是ACK还在传输过程中的未被确认的一定要小于rwnd这个必须得,多了就会丢包,发送端控制不了rwnd(因为是接收端的变量),所以通过可控制cwnd来控制发送方的速率。
第二个问题,一个TCP发送方如何感知从发送方到目的方产生了拥塞?
TCP把丢包定义为:超时和收到3个冗余ACK。拥塞时,可能是路由器的缓存满了,来了数据传输速率太快了,来不及发,只能存到缓存里,但是缓存也满了只能丢弃,这样就造成了丢包。当出现丢包的时候,发送方就会意识到已经遇到拥塞了。
第三个问题,感知到拥塞后,什么算法改变发送速率?
这就是下面要将的了!
1. 慢启动
发送方通过控制cwnd来控制发送速率。
开始的时候cwnd的值通常初始置为一个MSS的最小值,发送方想快速的找到可用带宽的数量。
每当报文段首部被确认,cwnd就会增加一个MSS,所以一个拥塞窗口的报文段都被确认之后,cwnd会增加一倍。就会是1,2,4,8…这样增长。
什么时候停止增长呐?
当出现超时或者丢包(拥塞了),TCP发送方会将cwnd设置为1,同时用变量ssthresh(“慢启动阈(yu)值”的速记)设置为拥塞窗口值得一半。当cwnd超过ssthresh时再翻倍就可能会拥塞了,所以此时转入拥塞避免。
2. 拥塞避免
拥塞避免就是在拥塞窗口内的报文全部确认后增加的长度为1MSS,也就是说每收到一个确认报文就增加MSS / cwnd。
何时停止增长?
和慢启动一样,拥塞了,cwnd置1,然后ssthresh标记为cwnd / 2,当cwnd大于等于ssthresh时进入快速恢复。
3.快速恢复
在快速恢复中,初始cwnd不置为1(也就是说不会在进行慢启动),首先cwnd = cwnd / 2,ssthresh = cwnd,,然后开始快速恢复:
1. 设置cwnd = ssthresh+ACK个数*MSS(一般情况下会是3个dup ACK)
2. 重传丢失的数据包
3. 如果只收到Dup ACK,那么cwnd = cwnd + 1, 并且在允许的条件下发送一个报文段
4. 如果收到新的ACK, 设置cwnd = ssthresh, 进入拥塞避免阶段
最后给出流程图(摘自博客园:http://www.cnblogs.com/stemon/p/4784142.html):