面试官:请说一下,TCP的拥塞控制是如何实现的?
流量控制是避免发送方的数据填满接收方的缓存。但计算机网络一般都处在一个共享的环境,因此也有可能会因为其他主机之间的通信使得网络拥堵。在网络出现拥堵时,如果继续发送大量数据包,可能会导致数据包丢失或者时延增大,这时TCP就会重传数据,而一重传就会导致网络的负担更重,于是会导致更大的延迟和更多的丢包。
图片
图片
图片
TCP的拥塞控制机制可以根据网络链路的实时状态,自动调整发送速度,降低发送的数据量,从而避免发送方的数据填满整个网络。
图片
图片
图片
TCP通过拥塞窗口来约束发送速度,拥塞窗口跟接收窗口类似,同样规定了发送方此刻能够发送出去的字节数,只不过它是通过评估网络链路的拥塞程度,并由一定的算法计算而来的。发送方的发送窗口大小由接收窗口和拥塞窗口共同决定,取拥塞窗口和接收窗口中的最小值。
图片
TCP通过慢启动、拥塞避免、拥塞发生和快速恢复四种算法来进行拥塞控制。
图片
1、慢启动
TCP连接刚建立时,对网络链路的运行状况一无所知,慢启动就是TCP启动后的发送速度慢慢的进行提速,便于感知网络的状况。
图片
慢启动算法将拥塞窗口cwnd初始化为1,然后每收到一个ACK,cwnd就会加 1,假设每个报文段都会回复ACK确认,在没有丢包的情况下,第一个分组被确认后,cwnd就变成了2,接下来,TCP可以发送2个报文段。如果这2个报文段均顺利送到,可以收到2个ACK确认,cwnd增大到 4,以此类推。因此,慢启动期间cwnd是呈指数增长的。
图片
图片
2、拥塞避免
当cwnd超过慢启动门限ssthresh时就会进入拥塞避免算法。在拥塞避免阶段,TCP以更慢的速度扩张拥塞窗口,每当成功发送跟拥塞窗口大小等量的数据并收到ACK确认后,cwnd就加1。例如,假设当前拥塞窗口大小为k,这时可以发出k个报文段。当这k个报文段均发出并收到确认后,才给cwnd加1,所以拥塞避免阶段,cwnd是呈线性增长的。
图片
图片
3、拥塞发生
进入拥塞避免阶段后,窗口保持缓慢增长,当遇到网络拥塞发送丢包时,TCP就会进行重传。如果是发生超时重传,慢启动门限ssthresh会被设置为当前拥塞窗口值的一半,cwnd恢复为初始化值1,然后重新开始前面的慢启动过程。如果是发生快速重传(重复ACK),ssthresh和cwnd都会变为当前拥塞窗口值的一半,然后进入到快速恢复阶段。
图片
图片
图片
图片
4、快速恢复
在快速恢复阶段,发送方会重传丢失的数据包,此时发送方已收到了3个重复的ACK,所以cwnd加3,如果再收到重复的 ACK,那么cwnd增加 1,如果收到新的ACK,表明重传的包成功了,将cwnd设置为当前的慢启动门限ssthresh值,然后再次进入到拥塞避免阶段。