单段长度上限
TCP_MAXSEG 是套接字选项,用来限制某条连接发送的 TCP 段能承载的最大数据字节数。正常连接中这个值由双方在握手时按路径 MTU 协商,应用层很少需要干预;当隧道、VPN 或中间设备把可用载荷压小,而路径 MTU 探测又失效时,才在连接级别压小段长,让报文不超路径承载能力。它只约束发送方向,不改变对端通告的值。
基本信息
| 适用平台 | Linux(选项名在不同系统上可能不存在或语义不同) |
|---|---|
| 取值单位 | 字节,常见取值 1200 至 1400 |
| 生效时机 | 连接建立前设置才能影响握手时通告的段长 |
| 查看方式 | 连接的 mss 字段;抓包看首个数据段长度 |
| 相关手段 | 路由级通告段长、全路径 MTU 探测参数 |
典型使用场景
- 隧道或 VPN 链路:外层封装挤占载荷,握手协商的段长仍然偏大。
- 中间设备丢弃 ICMP 需要分片消息,导致路径 MTU 探测失效与静默丢包。
- 复现 MTU 相关故障:在应用侧压小段长,验证现象是否消失以确认根因方向。
- 核对容器叠加网络中的实际段长是否符合预期。
- 确认路径 MTU 探测是否工作,而不是长期依赖固定段长绕过。
C 用例
C 用例
int mss = 1400; /* 按链路实际承载能力取值,不要凭感觉压到极小 */
if (setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &mss, sizeof(mss)) < 0) {
perror("setsockopt TCP_MAXSEG");
}验证生效
验证生效
ss -ti 'sport = :443' | head # 连接行中的 mss 字段即当前生效值
ip route get 203.0.113.10 # 查看该路由的 mtu 建议值
tcpdump -ni eth0 -c 5 'tcp port 443' # 观察首个数据段的实际长度是否与设置一致三个层次的手段
| 层次 | 手段 | 适用情况 |
|---|---|---|
| 应用连接级 | 连接选项设定段长 | 单条连接或单进程需要限制 |
| 路由级 | 为特定目标设置通告段长 | 同一目标的所有连接统一限制 |
| 全栈 | 启用路径 MTU 探测参数 | 中间设备过滤探测报文时的补救 |
把段长压得过小会降低有效吞吐:每个报文的头部与中断开销占比上升,需要按链路实际承载能力取值。
分片问题与连接卡死现象的根因通常是路径 MTU,直接在应用侧限制段长只是绕过;应在确认根因后决定是否长期保留这个设置。