为什么需要流量控制和拥塞控制?
TCP 作为面向连接的可靠传输协议,面临两个核心挑战:
- 接收方处理能力有限:如果发送方发送数据的速度超过接收方的处理能力,会导致接收缓冲区溢出,数据丢失。
- 网络承载能力有限:如果发送方发送数据的速度超过网络链路的承载能力,会导致网络拥塞,引发丢包、延迟增加等问题。
为解决这两个问题,TCP 设计了两套互补的控制机制:
- 流量控制:防止发送方淹没接收方(端到端控制)
- 拥塞控制:防止发送方淹没网络(全局控制)
流量控制:端到端的速率匹配
TCP 流量控制的目标是使发送方的发送速率与接收方的接收能力相匹配,避免接收缓冲区溢出。其核心实现是滑动窗口机制,由接收方通过 "接收窗口(rwnd)" 主动告知发送方可接受的数据量。
接收窗口(rwnd)的工作原理
-
接收窗口的定义:接收窗口是接收方当前可用的缓冲区大小,随接收方处理能力动态变化
-
窗口通告机制:
- 接收方在每个 ACK 报文的 "Window" 字段中告知发送方当前的 rwnd 值
- 如果接收缓冲区已满,rwnd 将设为 0,发送方会暂停发送
- 当接收方处理完部分数据释放缓冲区后,会主动发送一个携带新 rwnd 值的 ACK(窗口更新报文)
-
发送窗口的约束:发送方的未确认数据量不能超过接收窗口大小,即:
未确认数据量 ≤ rwnd
流量控制中的滑动窗口
TCP 滑动窗口是实现流量控制的核心技术,它通过维护一个动态变化的窗口来管理已发送但未确认、可发送但未发送的数据:
- 已发送且已确认:窗口左侧之前的数据,无需关注
- 已发送但未确认:窗口内左侧部分,等待接收方确认
- 未发送但可发送:窗口内右侧部分,可立即发送
- 未发送且不可发送:窗口右侧之外的数据,需等待窗口移动
当接收方确认数据后,窗口会向右滑动,释放出新的可发送空间。这种机制既保证了数据有序传输,又实现了接收方对发送速率的精确控制。
拥塞控制:网络全局的流量调控
拥塞控制关注的是整个网络的状态,目标是避免发送方发送的数据量超过网络链路的承载能力。与流量控制不同,拥塞控制主要由发送方根据网络状况自主调节,核心是拥塞窗口(cwnd) 机制。
拥塞窗口(cwnd)的基本概念
-
拥塞窗口:发送方根据网络拥塞状态估算的最大安全发送窗口,代表当前网络能够承载的数据量
-
实际发送窗口 :发送方最终能发送的最大数据量由拥塞窗口和接收窗口共同决定:
实际发送窗口 = min(cwnd, rwnd)
-
拥塞窗口的大小通过网络反馈动态调整,反映了发送方对网络状态的判断
TCP 拥塞控制的核心算法
TCP 拥塞控制通过四个阶段动态调整 cwnd 大小,经典实现包括:
-
慢启动(Slow Start)
- 初始阶段,cwnd 从较小值(通常为 1-2 个报文段)开始
- 每收到一个 ACK,cwnd 就加倍(指数增长)
- 直到 cwnd 达到慢启动阈值(ssthresh),进入拥塞避免阶段
- 目的:快速探测网络可用带宽,同时避免突然发送大量数据导致拥塞
-
拥塞避免(Congestion Avoidance)
- cwnd 达到 ssthresh 后,不再指数增长,而是每轮 RTT(往返时间)增加 1 个报文段(线性增长)
- 这种缓慢增长的方式避免网络突然拥塞
- 持续此阶段直到检测到网络拥塞
-
拥塞检测与恢复
- 当检测到丢包(超时或收到 3 个重复 ACK)时,认为网络出现拥塞
- 此时将 ssthresh 设为当前 cwnd 的一半,并重置 cwnd
- 根据丢包情况不同,有两种恢复策略:
- 超时重传:cwnd 重置为 1,重新进入慢启动
- 快速重传与快速恢复:cwnd 重置为 ssthresh,直接进入拥塞避免
现代 TCP 拥塞控制算法
随着网络发展,出现了许多改进的拥塞控制算法,如:
- CUBIC:Linux 默认算法,对长距离高带宽网络优化,采用三次函数增长
- BBR:由 Google 提出,基于瓶颈带宽和往返时间估算,更适合现代网络
- Vegas:通过测量实际吞吐量与预期吞吐量的差异来检测拥塞,更灵敏
这些算法在不同网络环境下各有优势,共同目标是在保证网络稳定的前提下最大化吞吐量。
流量控制与拥塞控制的协同工作
流量控制和拥塞控制并非孤立存在,而是通过 "实际发送窗口" 紧密协作:
- 发送方同时受限于接收方的处理能力(rwnd)和网络的承载能力(cwnd)
- 当接收方处理能力不足时(rwnd < cwnd),实际发送窗口由 rwnd 决定,体现流量控制
- 当网络拥塞时(cwnd < rwnd),实际发送窗口由 cwnd 决定,体现拥塞控制
- 两者共同作用,既保证数据能被接收方处理,又避免网络拥塞
这种协同机制使 TCP 能够在复杂多变的网络环境中自适应调整发送速率,实现高效可靠的数据传输。
两者的区别
-
流量控制的 "主动权在接收方":接收方通过告诉发送方 "我还能接多少数据"(接收窗口 rwnd),直接控制发送速率,防止自己处理不过来。就像快递收件人告诉快递员 "我家只能放 5 个包裹,多了放不下",收件人(接收方)主导节奏。
-
拥塞控制的 "决策在发送方":发送方通过观察网络状态(比如是否丢包、延迟是否增加),自己判断 "网络能承受多少数据"(拥塞窗口 cwnd),主动放慢或加快速度。就像司机看到前方堵车,会主动减速,不需要路人指挥,自己根据路况调整。