什么情况下才算发生了网络拥塞?
发送方有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确认报文
无论是在慢开始阶段还是拥塞避免阶段,做出以下调整:
- 把慢开始门限ssthresh设置为出现拥塞时发送方拥塞窗口大小的一半(不小于2)
- 拥塞窗口大小设为1,执行慢开始
目的:
迅速减少发送方发送到网络的报文数,在发生拥塞时路由器有足够的时间把队列中挤压的报文发完
快速重传
发送方收到了三个序号重复的ACK报文,认为该序号的报文丢失,则不等待定时器结束就直接重传该序号的报文
快速恢复
发送方收到了三个序号重复的ACK报文,认为该序号的报文丢失,慢开始门限设置为拥塞窗口大小的一半,拥塞窗口不设置为1,也设置为原窗口大小的一半,并执行拥塞避免算法,线性增大拥塞窗口。
因为跳过了拥塞窗口从1开始的慢开始过程,所以称为快恢复。
发送方窗口大小为 流量控制的滑动窗口和拥塞窗口 的较小值
快速重传有什么问题?
与基于定时器的超时重传拥有同样的问题,即:
不确定应该重发哪些序号的报文,如果只重发一个可能会拖慢整体传输时长,如果重发多个可能会浪费流量、增加整体传输时长,需要知道哪些序号的报文是丢失的,只重发丢失的报文。
发送方收到同一个序号的多个ACK确认,发送方并不清楚这些ACK是由哪些序号的报文传输成功后ACK回来的,可能会重发接收方已经收到的报文,浪费流量。
带选择确认的重传(SACK)解决了什么?
一端在发送ACK时通过在TCP报文头部增加SACK(Selective Acknowledgment)选项,告知对方已经收到的包序号区间范围,让对方只重传丢失的报文,并且可以一次性集中重传,避免了网络流量的浪费,也避免了长时间的超时等待。
SACK需要客户端和服务的都开启该功能