TCP拥塞算法

TCP拥塞算法

转载:https://cloud.tencent.com/developer/article/1488307

TCP拥塞算法TCP拥塞控制默认认为是丢包是由于网络丢包导致的。所以TCP拥塞算法 是以丢包作为网络进入拥塞状态的信号的。对于丢包有两种判断方式,一种是超时重传,一种是收到连续的三个重复ack。
RTO:发送端在发送一个数据后就开始计时,在一定时间内还没有收到这包数据的ACK就重传这包数据。
但是如果发送端接收到3个以上的重复ACK,TCP就意识到数据发生丢失,需要重传。这个机制不需要等到重传定时器超时,所以叫做快速重传,而快速重传后没有使用慢启动算法,而是拥塞避免算法,所以这又叫做快速恢复算法。
TCP拥塞算法
超时重传RTO[Retransmission Timeout]超时,TCP会重传数据包。TCP认为这种情况比较糟糕,反应也比较强烈:

由于发生丢包,将慢启动阈值ssthresh设置为当前cwnd的一半,即ssthresh = cwnd / 2.
cwnd重置为1
进入慢启动过程
最为早期的TCP Tahoe算法就使用上述处理办法,但是由于一丢包就一切重来,导致cwnd重置为1,十分不利于网络数据的稳定传递。

所以,TCP Reno算法进行了优化。当收到三个重复确认ACK时,TCP开启快速重传Fast Retransmit算法,而不用等到RTO超时再进行重传:

cwnd大小缩小为当前的一半
ssthresh设置为缩小后的cwnd大小
然后进入快速恢复算法Fast Recovery。
TCP拥塞算法
快速恢复算法 – Fast Recovery
TCP Tahoe是早期的算法,所以没有快速恢复算法,而Reno算法有。在进入快速恢复之前,cwnd和ssthresh已经被更改为原有cwnd的一半。快速恢复算法的逻辑如下:

cwnd = cwnd + 3 * MSS,加3 * MSS的原因是因为收到3个重复的ACK。
重传DACKs指定的数据包。
如果再收到DACKs,那么cwnd大小增加一。
如果收到新的ACK,表明重传的包成功了,那么退出快速恢复算法。将cwnd设置为ssthresh,然后进入拥塞避免算法。

如图所示,第五个包发生了丢失,所以导致接收方接收到三次重复ACK,也就是ACK5。所以将ssthresh设置为当时cwnd的一半,也就是6/2 = 3,cwnd设置为3 + 3 = 6。然后重传第五个包。当收到新的ACK时,也就是ACK11,则退出快速恢复阶段,将cwnd重新设置为当前的ssthresh,也就是3,然后进入拥塞避免算法阶段。

后记

本文为大家大致描述了TCP拥塞控制的一些机制,但是这些拥塞控制还是有很多缺陷和待优化的地方,业界也在不断推出新的拥塞控制算法,比如说谷歌的BBR。