拥塞控制是tcp中关键的点:学会并掌握拥塞控制,才能说你掌握了tcp传输协议;
首先我们要了解,接收方的接受缓存是有限的,接收方会通过TCP首部传输一个rwnd值(接收方窗口值)来通知发送方,发送的最大报文段个数不能超过接收方窗口值。真实的tcp发送方窗口上限值是由接收方的接受能力和网络拥塞情况控制的;
发送方窗口的上线值 = Min(rwnd,cwnd)
我们这篇文章主要讨论拥塞控制,因此我们忽略接收方的接受能力,即接收方缓存无限大,只考虑网络的拥塞和cwnd(拥塞窗口);
前提假设:
- 数据是单向的,接收方只传送确认报文;
- 假设接收方的存储缓存足够大,即发送方的发送窗口由网络的拥塞程度来决定;
拥塞控制的方法:
1.慢开始(slow-start)
发送方维护了一个拥塞窗口cwnd,原则上,在不出现网络拥塞的情况下(分组确认超时),拥塞窗口可以一直增加;
慢开始算法的思路是:在不清楚网络负载的前提下,有小到大,成倍的增大发送窗口和拥塞窗口;
新的RFC 5681规定,初始拥塞窗口更加最大报文段SMSS的数值而定,具体情况不说了,即初始cwnd有可能是2,3,4个SMSS;
之后发送方没接受到一个报文确认,可立即将cwnd增加一个SMSS;由此看来,在慢开始阶段,cwnd和发送方发送窗口是每个传输轮次都成倍增加的;但是cwnd也不可能无限增加,tcp还引入了一个慢开始门限ssthresh(slow start thresh);当cwnd超过ssthresh时,即开始拥塞避免也就是下个拥塞控制的方法。
2.拥塞避免
拥塞避免算法的思路是让拥塞窗口cwnd缓慢的增大,一个RTT把发送方的拥塞窗口值加一,而不是像慢开始那样成倍的增长,也称为“加法增大”(AI);
当拥塞避免算法使拥塞窗口缓慢增大时,假设增大到某个值,网络中出现了超时。
一旦发生超时,tcp协议即将慢开始门限值ssthresh调整为 :
ssthresh = cwnd/2;
此时的拥塞窗口调整为初始拥塞窗口;重新进入慢开始阶段;
3.快重传
采用快重传算法算法使为了,尽早的让对方知道某个报文段已经丢失,可以避免超时导致的慢开始导致的传输速率降低。
接收方发现某个报文段丢失即刻发送“重复确认某报文段”的确认消息给发送方,发送方连续收到3个重复确认,即判定接收方丢失某个报文段,立即重传(即“快重传”)。
4.快恢复
当发送方确认只是丢失个别报文段,不启用慢开始而是启用快恢复:
快恢复:将发送方的慢开始门限值调整为下面这个公式,称为“乘法减小”;
ssthresh = max(FlightSize/2,2*SMSS); FlightSize为当前网络中传输的数据量,
可简化成门限阈值(ssthresh)为cwnd的一半,然后cwnd等于门限阈值
也有的快恢复算法使把ssthresh的值加3*SMSS;