模块二 · 运输层
拥塞控制
上一章的流量控制是"别压垮接收方"。但还有另一个问题:别压垮中间的网络。如果所有人都猛发,路由器队列会溢出、丢包加剧,最后所有人都变慢。本章讲 TCP 怎么在不能直接看到全路径容量,但可利用ECN等反馈的情况下,自己估算出该发多快。
本章要解决的问题:上一章的流量控制是"别压垮接收方"。但还有另一个问题:别压垮中间的网络。如果所有人都猛发,路由器队列会溢出、丢包加剧,最后所有人都变慢。本章讲 TCP 怎么在不能直接看到全路径容量,但可利用ECN等反馈的情况下,自己估算出该发多快。
本章的证据来源:历史实测记录(Get-NetTCPSetting 与 netsh int tcp show global 的拥塞控制相关参数)。算法原理出自 RFC 5681(TCP 拥塞控制)。
先从一个例子理解概念
路口一次只能通过有限车辆,超过能力就会排队。网络出口和设备处理能力也有限,发送端需要控制进入路径的数据量。
中间网络承受不住:拥塞
请求的数据传输量超过某处可持续处理能力,造成排队、损失等情况,叫拥塞。它与接收端缓冲不够不是同一个问题。
先试探再调整:慢启动与拥塞避免
慢启动从较小发送规模开始试探,增长可以很快;拥塞避免在已探索的范围附近更谨慎地增长。具体曲线随算法变化。
反馈可以不用先丢包:ECN
ECN(显式拥塞通知)允许支持的节点标记拥塞,再反馈给发送端。它不是给整个互联网广播一个通知,也不是要求每台普通转发设备都支持。
不同调整办法:Reno、CUBIC与BBR
这些是拥塞控制算法名,不是网速档位。Reno是经典框架,CUBIC使用三次函数等规则,BBR按送达率和RTT建模;不能把某一种公式套给全部算法。
下面再用这些概念看原理、命令和结果。规范与官方资料列在本章末尾,类比只帮助理解,不代替协议规则。
两个"别发太快"
| 机制 | 保护对象 | 主要信息来源 |
|---|---|---|
| 流量控制 | 接收端缓冲区 | 接收端通告的rwnd |
| 拥塞控制 | 路径中的网络资源 | 丢包、RTT、送达率或ECN反馈,因算法而异 |
发送端通常不知道全路径容量,需通过信号估计。传统丢包型算法把丢包作为拥塞信号;支持ECN的节点也能标记拥塞,由接收端反馈。因此不能说“网络中间永远不会通知”。RFC 3168
拥塞窗口:发送方自己估算的"网络容量"
发送方维护一个自己的变量:拥塞窗口(cwnd)。
它的含义是:"我估计现在的网络能承受这么多在途数据。"
于是发送方能发多少,由两个窗口共同决定:
实际能发多少 = min( 接收方通告的窗口 , 自己的拥塞窗口 )
↑ 流量控制 ↑ 拥塞控制注意拥塞窗口不在任何报文里传输 —— 它是发送方自己算出来的,接收方根本不知道这个值。这是它和接收窗口最大的区别。
拥塞控制的四个阶段
下面描述RFC5681的经典框架,不是所有TCP算法都严格使用同一增长与减小公式。
慢启动与拥塞避免
慢启动从初始窗口开始,随ACK增加窗口,理想条件下近似每RTT增长一倍;确认策略和算法会影响实际轨迹。到阈值后,经典Reno拥塞避免约每RTT增加一个SMSS。
快速重传与恢复
经典算法收到足够重复ACK可推定丢失并重传。RFC5681按FlightSize设定ssthresh,进入/退出快速恢复时还有窗口调整,不能把整个过程说成“cwnd直接除二”。CUBIC则使用自己的增长曲线及减小因子,RFC9438推荐beta=0.7。
超时恢复
RTO到期可触发保守恢复,经典算法把拥塞窗口限制到一个SMSS并重新慢启动;这里是一个段的数据量,不是1字节。超时可能是尾部丢失、ACK丢失等,不能单独证明比快速重传时更严重的拥塞。
历史设置中HyStart与PRR开启,只说明当时查询的策略;不证明具体连接实际执行轨迹。RFC 5681 §3、RFC 9438 §4.5
实测:本机用的是 CUBIC
Get-NetTCPSetting实测结果:
| 设置档 | 拥塞算法 | MinRto |
|---|---|---|
| InternetCustom | CUBIC | 300 ms |
| DatacenterCustom | CUBIC | 60 ms |
| Compat | NewReno | 300 ms |
互联网档用的是 CUBIC,兼容档还保留着 NewReno。
为什么不用经典的 Reno 了
经典算法(Reno)在高带宽、长延迟的链路上有个致命问题:
Reno 的线性增长是"每个 RTT 加 1 个段"
→ RTT 是 200ms 的话,一秒只能加 5 个段
→ 从"减半"恢复到原来的窗口,要花很长时间
→ 结果:一旦丢包,带宽利用率要很久才能恢复CUBIC 改了增长曲线:不用线性,而用三次函数:
离上次拥塞点越远 → 增长越快(快速恢复带宽)
接近上次拥塞点 → 增长越慢(小心试探)这个设计的好处:不管 RTT 多长,恢复速度都差不多(因为曲线的自变量是时间,不是 RTT 轮次)。这让 CUBIC 在高带宽长延迟的链路上明显优于 Reno。
各代算法对比:
| 算法 | 特点 |
|---|---|
| Tahoe | 最早的实现,丢包一律回到起点(太保守) |
| Reno | 引入快速恢复,丢包减半 |
| NewReno | 改进快速恢复,能处理一个窗口内多个丢包 |
| CUBIC | 使用三次函数增长,系统是否默认及实际使用需查版本/连接 |
| BBR | 根据送达率与RTT建模;不同版本对丢包/ECN的反应不同,不能一概说丢包不降速 |
实测:其他几个相关开关
ECN Capability : disabled
HyStart : enabled
Proportional Rate Reduction : enabled
Pacing Profile : off| 参数 | 状态 | 含义 |
|---|---|---|
| ECN | 关闭 | 显式拥塞通知 —— 让路由器主动标记"我堵了"而不是等丢包。这是对"丢包=拥塞"假设的改良,需要端系统协商且标记/反馈正确;普通不支持ECN的转发节点不必使整条路径失效 |
| HyStart | 开启 | 用 RTT 变化提前判断慢启动该退出了 |
| PRR | 开启 | 快速恢复期间平滑降速,避免震荡 |
| Pacing | 关闭 | 把数据按时间均匀"配速"发送,而不是一次发一批。对减少突发丢包有帮助,但会增加 CPU 开销 |
"丢包 = 拥塞"这个假设的局限
传统拥塞控制建立在一个假设上:丢包说明路上堵了。 但这个假设在某些场景下不成立:
| 场景 | 丢包的真实原因 | 传统 TCP 的错误反应 |
|---|---|---|
| Wi-Fi 信号差 | 无线干扰、距离远 | 以为是拥塞,白白降速 |
| 移动网络切换基站 | 链路短暂中断 | 同上 |
| 链路本身有误码 | 线路质量 | 同上 |
结果是:在这些场景下,TCP 会误判为拥塞而反复降速,性能远低于链路实际能力。
BBR 就是针对这个问题提出的:它不去猜测"丢包意味着什么",而是直接测量两个物理量 —— 链路的瓶颈带宽和最小往返延迟,然后按这两个值来发。具体恢复与降速行为要看BBR版本和实现,不能保证有丢包也永不降速。
常见误解
拥塞控制不是只能靠丢包。 ECN等机制可反馈拥塞,算法还可能利用RTT和送达率。
慢启动不保证每轮严格翻倍。 这是理想化近似,实际还受ACK、窗口、应用发送量和具体算法影响。
拥塞窗口不是接收窗口字段。 cwnd是发送端内部状态,rwnd通过TCP窗口通告;新增发送量还需考虑已经在途的数据。
丢包不一定来自拥塞,BBR也不是永远忽略丢包。 无线误码和切换可引起损失;选择算法与调参需要对应版本和测量。
本章小结
| 结论 | 性质 |
|---|---|
| 流量控制保护接收端,拥塞控制管理网络负载 | 协议概念 |
| 在途数据受cwnd和rwnd共同约束 | RFC 5681 |
| 丢包、ECN和时延等可作为算法输入 | 算法范围 |
| Reno与CUBIC增长和恢复规则不同,不能混用减半公式 | RFC 5681 / 9438 |
| 历史CUBIC、HyStart、PRR设置不替代逐连接协商与行为观察 | 历史观察 |
自测题
7 题 · 先自己答,再展开对照
流量控制和拥塞控制分别要保护谁?为什么一个能"明确知道",另一个只能"猜"?
流量控制保护接收端,由rwnd通告;拥塞控制保护网络资源,可依据丢包、RTT、送达率或ECN等信号估计,不是永远没有直接反馈。拥塞窗口和接收窗口最关键的区别是什么?
拥塞窗口是发送方自己算出来的,不通过网络传输;接收窗口是接收方在 ACK 中明确通告的。 也就是说,接收方完全不知道发送方用的拥塞窗口是多少。发送方实际能发多少,取这两个窗口的较小值。慢启动"慢"在哪里?它的增长速度是怎样的?
"慢"指的是起点很小 —— 不会一上来就发满,而是从几个段开始。但它的增长是指数级的(每经过一个 RTT 窗口翻倍),所以实际上很快就涨上来了:从 2 个段翻倍到 1000 个段只需要约 9 个 RTT。这个名字是相对于"一开始就发满"而言的。收到 3 个重复 ACK 和发生 RTO 超时,TCP 的反应有什么不同?为什么?
经典快速重传/恢复与RTO恢复不同,但减小公式要指定算法、FlightSize和窗口单位。CUBIC不能直接套Reno减半;超时也不能独自证明严重拥塞。CUBIC 相比 Reno 解决了什么问题?
解决了 Reno 在高带宽长延迟链路上"恢复太慢"的问题。 Reno 的线性增长是"每个 RTT 加 1 个段",RTT 越大恢复越慢(RTT 200ms 时一秒只能加 5 个段)。CUBIC 改用三次函数增长 —— 自变量是时间而不是 RTT 轮次,所以不管 RTT 多长,恢复到上次拥塞点附近所需的时间都差不多。你用 Wi-Fi 下载文件,信号偶尔不好。传统 TCP 会怎么反应?这是最优的做法吗?
无线损失可能被丢包型算法按拥塞处理;是否造成明显性能问题需测量。BBR依版本采用不同模型与损失反应,不能保证丢包时不降速。历史实测记录
ECN Capability : disabled。ECN 是什么?开着有什么好处?ECN让支持的拥塞节点标记并由端系统反馈,减小依赖丢包通知的代价。两端需协商,但不是全路径每台普通转发设备都必须实现ECN;配置值不代表实际连接已协商。
参考资料与适用范围
修订核对日期:2026-10-13。规则按所列协议与实现范围理解;文中的原始命令输出是历史观察,不表示本次重新实测。跨版本、代理/隧道及不同捕获位置需要另行核对。