TCP Congestion Control
TCP 通过减小发送窗口大小来处理拥塞,发送窗口的大小由以下两个因素共同决定:
- 接收窗口大小(Receiver window)
- 拥塞窗口大小(Congestion window)
接收窗口大小
接收窗口大小是一种接收端对发送端的告知:用来说明接收者总计能接收多少字节未确认数据
- 发送端发送的数据量不得大于接收窗口大小,否则会存在 TCP 报文丢失进而导致 TCP 重传(TCP Retransmission)
- 发送端发送的数据量应小于等于接收窗口大小,发送者通过 TCP 头(TCP Header)得知接收者接收窗口大小
拥塞窗口大小
- 发送端发送的未确认数据不得大于拥塞窗口大小,否则会使得 TCP 报文段丢弃进而导致 TCP 重传
- 发送者发送的未确认数据应小于等于拥塞窗口大小,拥塞窗口的概念只存在于发送端
发送窗口的大小取接收窗口和拥塞窗口的最小值
Sender window size = Minimum (Receiver window size, Congestion window size)
TCP 应对拥塞的策略
TCP 应对拥塞的策略由三阶段组成:慢启动(Slow Start),拥塞避免(Congestion Avoidance)和拥塞探知(Congestion Detection)
慢启动阶段
一开始发送端设置拥塞窗口等于一个最大报文段(1 MSS)。在接收到确认 ACK 后,发送端把拥塞窗口增加 1 MSS,整个过程中拥塞窗口按照预设规则增大(指数级)
Congestion window size = Congestion window size + Maximum segment size
一轮 ACK 过后,拥塞窗口 = $(2)^1$ = 2 MSS
二轮 ACK 过后,拥塞窗口 = $(2)^2$ = 4 MSS
三轮 ACK 过后,拥塞窗口 = $(2)^3$ = 8 MSS
......
整个过程一直持续,直到拥塞窗口大小达到慢启动阈值(slow start threshold)
Threshold = Maximum number of TCP segments that receiver window can accommodate / 2
= (Receiver window size / Maximum Segment Size) / 2
拥塞避免阶段
拥塞窗口达到阈值后,为避免拥塞发送端改为线性的增加拥塞窗口大小
接收到每个 ACK 后,发送端只对拥塞窗口增加 1 MSS
Congestion window size = Congestion window size + 1
整个过程一直持续,直到拥塞窗口大小增大到接收窗口大小
拥塞感知阶段
发送端检测到报文丢失时,根据不同方式感知到的报文丢失会采取不同的策略来处理
方式一:通过超时感知拥塞(Time Out)
接收者经历超时时间后却没收到报文确认 ACK,说明有大概率存在网络拥塞,这时报文段可能已经丢失
发送端的应对策略:
- 设置慢启动阈值为当前拥塞窗口大小的一半
- 设置拥塞窗口大小为 1 MSS
- 恢复到慢启动阶段
方式二:收到三个重复 ACK 感知拥塞
发送端接收到三个重复的 ACK 说明存在小概率网络拥塞,
虽然报文存在丢失的可能,但接下来发送的报文应该可以顺利到达
发送端的应对策略:
- 设置慢启动阈值为当前拥塞窗口大小的一半
- 拥塞窗口减小到慢启动阈值
- 恢复到拥塞避免阶段
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。