5.7 TCP 的拥塞控制
当网络中数据量超过了设备的处理能力时,则称发生了网络拥塞。此时会导致数据报的丢失等情况,会导致数据传输效率降低,用户体验变差。
网络拥塞可以发生在网络的任何地方,包括但不限于路由器、交换机、用户端设备等。
(P241 5.8.2)当分组丢失后,TCP 会发生超时重传,此时 TCP 即认为可能发生了网络拥塞。即:只要出现了超时重传,TCP 就认为发生了网络拥塞。
发送方维护一个拥塞窗口 cwnd(Congestion Window),真正的发送窗口取对方接收窗口和我方拥塞窗口之间的最小值。此节中假设接收方接收窗口无限大,且数据发送时单向的,即此节仅讨论一个理想情况:发送窗口仅取决于拥塞窗口、接收方仅发送确认报文。
此节为讨论方便,拥塞发送窗口和发送的数据单位为 ,即 1 个发送方最大报文段。
TCP 进行拥塞控制的算法有四种:慢开始(Slow-Start)和拥塞避免(Congestion Avoidance)、快重传(Fast Retransmit)和快恢复(Fast Recovery)。
TCP 实现必须实现慢开始、拥塞避免和 RTO 指数退避算法以完成拥塞控制。
相关词条:
-
初始拥塞窗口 IW(Initial Window)
初始拥塞窗口由 SMSS 决定:
- 当 时,拥塞窗口为 ,且不得超过 2 个报文段。
- 当 时,拥塞窗口为 ,且不得超过 3 个报文段。
- 当 时,拥塞窗口为 ,且不得超过 4 个报文段。
并且:
- 当握手过程中 SYN 和 SYN/ACK 报文丢失时,拥塞窗口初始值不得超过 ,且不得超过 1 个报文段。
-
慢开始门限 ssthresh
当拥塞窗口大小超过 ssthresh 时,则改用拥塞避免算法。ssthresh 初始值应当设置为任意高的值(例如最大可能的通告窗口的大小)。
5.7.1 慢开始和拥塞避免
(RFC-5681 3.1)慢开始的主要思路是,从小到大逐渐改变拥塞窗口的数值,逐渐增加注入到网络中的数据。具体的:
- 当拥塞窗口即 cwnd 不超过慢开始门限 ssthresh 时,使用慢开始算法,即每收到 1 个报文段的确认,则将 cwnd +1。慢开始实际含义为从慢速开始,实际 cwnd 大小的增长为指数型的。
- 当 cwnd 超过 ssthresh 时,使用拥塞避免算法,即每发送一个拥塞窗口的数据,并收到了所有发送的数据的确认(又称每经过一个 RTT),则将 cwnd +1。
- 当发生超时重传,即发生网络拥塞时,ssthresh 减小为当前 cwnd 的一半,并将 cwnd 重置为初始值,重新开始执行慢开始算法。
并且:
- SYN 和 SYN/ACK 报文不得增加 cwnd。
5.7.2 快重传和快恢复
(RFC-5681 3.2)快重传和快恢复是建立在慢开始和拥塞避免机制基础之上,针对数据丢失的情况进行的优化。
快重传要求接收方:
- 不得进行延迟确认,即收到一个分组应立即发送确认。
- 不得进行选择确认,当分组乱序到达时,应对已连续正确收到的字节需要重复发 送确认。
快重传指当接收方收到对三个重复序号的 ACK 时,则视为发生了网络拥塞,此时立即进行重传,而非等待超时后重传。
快恢复指当发生网络拥塞时,在将 ssthresh 减小为当前 cwnd 的一半之后,将 cwnd 减小为 ssthresh,而非初始值,然后执行慢开始算法。