0%

TCP拥塞控制

什么情况下才算发生了网络拥塞?

发送方有TCP报文超时了没有收到ACK确认报文

拥塞控制的过程是怎样的?

慢启动、拥塞避免、快重传、快恢复

拥塞窗口,拥塞窗口大小cwnd(congestion window)表示可以发送的报文字节数,单位是一个MSS(最大报文长度)

慢启动

拥塞窗口初始大小为1,每收到一个ACK,拥塞窗口大小+1,实际效果就是每过一个RTT,拥塞窗口大小为原来的2倍,以指数增长率增长,先慢后快,达到慢开始门限ssthresh则停止慢开始,执行拥塞避免算法。

翻倍后如果大小超过阈值则窗口大小设为阈值。

例如:

初始窗口大小为1

发送第一个报文M0,收到ACK1后窗口大小+1,变为2

发送M1、M2,收到ACK2、ACK3后,窗口大小+2,变为4

再发送4个报文,收到4个ACK后,窗口大小+4,变为8

拥塞避免

每过一个RTT(受到一个ACK),拥塞窗口大小+1

线性增长,避免增长过快

发生拥塞

发送方有报文超时,未收到ACK确认报文

无论是在慢开始阶段还是拥塞避免阶段,做出以下调整:

  1. 把慢开始门限ssthresh设置为出现拥塞时发送方拥塞窗口大小的一半(不小于2)
  2. 拥塞窗口大小设为1,执行慢开始

目的:

迅速减少发送方发送到网络的报文数,在发生拥塞时路由器有足够的时间把队列中挤压的报文发完

快速重传

发送方收到了三个序号重复的ACK报文,认为该序号的报文丢失,则不等待定时器结束就直接重传该序号的报文

快速恢复

发送方收到了三个序号重复的ACK报文,认为该序号的报文丢失,慢开始门限设置为拥塞窗口大小的一半,拥塞窗口不设置为1,也设置为原窗口大小的一半,并执行拥塞避免算法,线性增大拥塞窗口。

因为跳过了拥塞窗口从1开始的慢开始过程,所以称为快恢复。

发送方窗口大小为 流量控制的滑动窗口和拥塞窗口 的较小值

快速重传有什么问题?

与基于定时器的超时重传拥有同样的问题,即:

不确定应该重发哪些序号的报文,如果只重发一个可能会拖慢整体传输时长,如果重发多个可能会浪费流量、增加整体传输时长,需要知道哪些序号的报文是丢失的,只重发丢失的报文。

发送方收到同一个序号的多个ACK确认,发送方并不清楚这些ACK是由哪些序号的报文传输成功后ACK回来的,可能会重发接收方已经收到的报文,浪费流量。

带选择确认的重传(SACK)解决了什么?

一端在发送ACK时通过在TCP报文头部增加SACK(Selective Acknowledgment)选项,告知对方已经收到的包序号区间范围,让对方只重传丢失的报文,并且可以一次性集中重传,避免了网络流量的浪费,也避免了长时间的超时等待。

SACK需要客户端和服务的都开启该功能