TCP ECN:让路由器"提前喊挤",而不是靠丢包
更新时间:2026-09-17。网络协议域·传输层。它是对拥塞控制"只靠丢包判断拥塞"的补充——把信号提前到队列将满、尚未丢包时。
传统 TCP 把丢包当作拥塞信号:路由器缓冲区满了只能丢包,发送方靠超时或重复 ACK 才发现、再降速。这既浪费已发送的带宽,反应也偏晚。**ECN(Explicit Congestion Notification,显式拥塞通知,RFC 3168)**让网络设备在队列开始变长时就在包头打一个"我有点挤了"的标记,端系统据此提前降速,避免真的丢包。
一、两处标记:IP 层 + TCP 层
ECN 需要发送端、接收端、沿途路由器都支持并协商。它复用了 IP 头的 DSCP 字段中两位 ECN 字段,并在 TCP 头用两个标志配合:
IP 头 ECN 两位的四种取值:
| 值 | 含义 |
|---|---|
00 Non-ECT | 不支持 ECN 的包 |
01 ECT(1) / 10 ECT(0) | ECN-Capable Transport,表示本包支持 ECN |
11 CE(Congestion Experienced) | 路由器打的"已发生拥塞"标记 |
TCP 头两个标志:
- ECE(ECN-Echo):接收方在回 ACK 时置位,转告发送方"我收到了 CE 标记的包"。
- CWR(Congestion Window Reduced):发送方降窗后置位,告诉接收方"我已收到并处理了拥塞信号"。
二、协商与一次完整反馈
- 协商:建连 SYN/SYN-ACK 双方带 ECE+CWR(ECE、CWR 两位同时置 1 表示"我支持 ECN"),后续数据包才用 ECT 标记。
- 途中标记:支持 AQM(如 RED/WRED)的路由器在队列将满但未满时,把 ECT 包改成 CE,而不是丢弃。
- 回传:接收方看到 CE,在接下来的 ACK 里持续置 ECE。
- 降速:发送方收到 ECE,像快恢复一样把 cwnd/ssthresh 降低,并回一个置 CWR 的包确认已响应;接收方随后停止重复 ECE。
发送端 --ECT包--> [路由器队列将满: 改 CE] --CE包--> 接收端
发送端 <-- ACK(ECE)------ 接收端(转告拥塞)
发送端 -- 降低 cwnd, 发 CWR 确认 -->收益:把"丢包→重传→超时"的重代价,换成"标记→提前降窗",降低丢包率与抖动,在 AQM 部署良好的网络(数据中心、部分移动/骨干)改善延迟。
三、前提:必须有 AQM,不是改了端就生效
ECN 标记由网络中间设备做出,传统的简单尾丢弃(tail-drop)队列只会丢包、不会打 CE。所以 ECN 要发挥作用,需要路由器启用主动队列管理(RED、WRED、CoDel、PIE、fq_codel 等),在队列早期就标记。这也是为什么 ECN 与"缓冲膨胀治理"(见 tc 与 fq_codel)常常一起出现。
- 在数据中心,DCTCP 大量依赖 ECN 比例来精细、成比例地调整窗口。
- 广域网上 ECN 协商成功与否取决于路径上所有设备;部分老设备错误处理 CE 会导致连通问题,因此实现都有"协商失败即回退"机制。
- L4S(RFC 9330)等新标准用更精细的 ECN 标记实现极低延迟,是 ECN 的演进。
四、Linux 开关与观测
sysctl net.ipv4.tcp_ecn
# 0 = 不主动对出站连接用 ECN(仍可响应入站协商)
# 1 = 对出站连接启用 ECN(服务端/服务器常用)
# 2 = 对所有连接启用(更激进)
sysctl -w net.ipv4.tcp_ecn=1# 抓包看 SYN 是否协商 ECN、是否出现 ECE/CWR
tcpdump -nn -i any 'tcp[tcpflags] & (tcp-ece|tcp-cwr) != 0'
# Wireshark 过滤 tcp.flags.ecn==1 / ip.dsfield.ecn==3(CE)
ss -ti | grep -i ecn # 连接是否协商上 ECN(部分版本显示)注意:仅把 tcp_ecn 打开、而路径 AQM 不标记,实际不会有 CE,行为与普通拥塞控制无异;它是"有则受益、无则回退"的能力。
五、与其他机制的关系
| 机制 | 信号 | 时机 |
|---|---|---|
| 丢包驱动(Reno/CUBIC) | 超时 / 3 dup ACK | 丢包之后 |
| ECN | 路由器 CE 标记 | 丢包之前,队列将满 |
| 延迟驱动(Vegas/BBR 部分) | RTT/带宽估计 | 排队延迟上升时 |
| DCTCP/L4S | ECN 标记比例 | 精细、低延迟数据中心/广域 |
ECN 不改变"最终要降 cwnd"的拥塞控制本质,只是提供了更早、更省的输入信号。
相关阅读
降窗/快恢复机制见 TCP 拥塞控制,队列与 AQM(fq_codel/cake)见 tc 命令,重传见 重传与 RTO。
总结
ECN 在 IP 头用 ECT/CE、在 TCP 头用 ECE/CWR 协同:支持 ECN 的包经过将满队列时由 AQM 路由器打 CE 标记而非丢弃,接收端以 ECE 转告、发送端像快恢复一样提前降低 cwnd 并回 CWR,从而在丢包前就缓解拥塞;前提是端侧(tcp_ecn)协商且路径有 RED/CoDel 等 AQM,无标记时自动回退到普通丢包拥塞控制。