知识点编号:028
难度等级:⭐⭐(必掌握)
面试频率:🔥🔥🔥🔥
🎯 一句话总结
MTU是快递箱子的大小,MSS是箱子里能装的东西的大小!📦
🤔 MTU和MSS是什么?
MTU(Maximum Transmission Unit)
最大传输单元
链路层一次能传输的最大数据包大小
常见值:
- 以太网:1500字节(最常见)
- PPPoE:1492字节
- VPN:通常更小(1400左右)
- 环回接口:65535字节
组成:
MTU = IP头部 + TCP/UDP头部 + 数据
1500 = 20 + 20 + 1460
生活比喻:
快递箱子的大小限制
- 箱子最大只能装1500个单位的东西
- 包括包装纸(IP头)、泡沫(TCP头)、货物(数据)
MSS(Maximum Segment Size)
最大段大小
TCP一次能发送的最大数据大小(不含头部)
计算:
MSS = MTU - IP头部 - TCP头部
MSS = 1500 - 20 - 20 = 1460字节
特点:
- 只是数据部分,不含头部
- TCP专用(UDP没有MSS)
- 三次握手时协商
生活比喻:
箱子里能装的货物大小
- 箱子1500,包装纸20,泡沫20
- 货物最多1460
📊 关系图
[================== MTU (1500字节) ==================]
[IP头20][TCP头20][========== 数据 (1460字节) ==========]
[========== MSS ==========]
分层视角:
链路层:MTU(整个数据包)
网络层:MTU - IP头
传输层:MSS(TCP数据)
应用层:MSS(能用的数据空间)
🔍 常见MTU值
网络类型 MTU
─────────────────────────
以太网 1500
Wi-Fi 1500
PPPoE ADSL 1492
VPN (IPSec) ~1400
VPN (GRE) ~1476
VLAN 1496
Jumbo Frame 9000
环回接口 65535
为什么PPPoE是1492?
PPPoE头部:8字节
1500 - 8 = 1492
🤝 MSS协商过程
三次握手中的MSS协商
客户端 服务器
| |
| SYN, MSS=1460 |
|----------------------------->|
| |
| SYN+ACK, MSS=1460 |
|<-----------------------------|
| |
| ACK |
|----------------------------->|
| |
结果:双方使用 min(1460, 1460) = 1460
如果不同:
客户端 MSS=1460
服务器 MSS=1400
使用:min(1460, 1400) = 1400
⚠️ MTU不匹配的问题
问题场景
客户端 → MTU=1500 → VPN → MTU=1400 → 服务器
客户端发送1500字节包:
1. 到达VPN,MTU=1400
2. 需要分片!
3. 分成2个包:1400 + 100
4. 性能下降
解决方案:
在客户端设置MTU=1400
或使用PMTUD(路径MTU发现)
DF标志的作用
DF=1(Don't Fragment):
- 不允许分片
- 如果包太大,丢弃
- 返回ICMP "Fragmentation Needed"
- 用于PMTUD
DF=0:
- 允许分片
- 路由器可以分片
💻 Java代码示例
查看MTU
import java.net.*;
public class MTUChecker {
public static void main(String[] args) {
try {
// 获取所有网络接口
for (NetworkInterface ni :
Collections.list(NetworkInterface.getNetworkInterfaces())) {
if (!ni.isUp()) continue;
System.out.println("\n接口: " + ni.getName());
System.out.println(" 显示名: " + ni.getDisplayName());
System.out.println(" MTU: " + ni.getMTU() + " 字节");
// 计算MSS
int mtu = ni.getMTU();
int mss = mtu - 20 - 20; // IP头 + TCP头
System.out.println(" MSS: " + mss + " 字节");
// 获取IP地址
for (InetAddress addr :
Collections.list(ni.getInetAddresses())) {
System.out.println(" 地址: " + addr.getHostAddress());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
测试MTU(ping命令)
# Windows
ping -f -l 1472 www.baidu.com
# -f: 设置DF标志(不分片)
# -l 1472: 数据大小
# 1472 + 20(IP头) + 8(ICMP头) = 1500
# 如果成功,MTU≥1500
# 如果失败,MTU<1500,减小数据大小重试
# Linux
ping -M do -s 1472 www.baidu.com
# -M do: 设置DF标志
# -s 1472: 数据大小
🔧 优化建议
1. 设置合适的MTU
场景1:普通以太网
MTU = 1500(默认)
MSS = 1460
✅ 不需要调整
场景2:VPN环境
MTU = 1400(减小以适应VPN开销)
MSS = 1360
✅ 避免分片
场景3:高性能网络
MTU = 9000(Jumbo Frame)
MSS = 8960
✅ 减少包数量,提高吞吐量
2. 路径MTU发现
PMTUD(Path MTU Discovery):
过程:
1. 设置DF=1,发送大包
2. 如果路由器MTU小,返回ICMP错误
3. 减小包大小,重试
4. 找到最小MTU
Java中:
// 无法直接控制PMTUD
// 由操作系统TCP栈自动处理
Linux开启PMTUD:
net.ipv4.ip_no_pmtu_disc = 0
3. TCP MSS Clamping
在路由器上限制MSS:
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN \
-j TCPMSS --set-mss 1360
作用:
- 修改SYN包中的MSS选项
- 防止过大的MSS导致分片
- 适用于VPN等场景
🐛 常见面试题
Q1:MTU和MSS的区别是什么?
答案:
MTU(Maximum Transmission Unit):
- 最大传输单元
- 链路层概念
- 整个IP包的大小
- 包含:IP头 + TCP头 + 数据
- 示例:1500字节
MSS(Maximum Segment Size):
- 最大段大小
- TCP层概念
- 只是TCP数据的大小
- 不包含任何头部
- 示例:1460字节
关系:
MSS = MTU - IP头(20) - TCP头(20)
1460 = 1500 - 20 - 20
生活比喻:
MTU = 快递箱子大小(包括箱子本身)
MSS = 箱子里能装的东西大小(不含箱子)
协商:
- MTU:链路层决定
- MSS:TCP三次握手时协商
- 双方使用较小的MSS
Q2:如何解决MTU不匹配问题?
答案:
问题:
客户端MTU=1500
中间路由MTU=1400
→ 需要分片,性能下降
解决方案:
1. 调整客户端MTU(推荐)
- 手动设置MTU=1400
- 避免分片
2. 路径MTU发现(PMTUD)
- 设置DF标志
- 自动发现最小MTU
- 按最小MTU发送
3. TCP MSS Clamping
- 路由器修改MSS
- 限制TCP段大小
4. 分片重组
- 允许分片(DF=0)
- 性能较差,不推荐
最佳实践:
- VPN环境:MTU=1400
- 云环境:按云厂商建议
- 普通网络:MTU=1500(默认)
- 高性能网络:MTU=9000(Jumbo Frame)
验证方法:
ping -f -l 1472 目标IP
逐步减小直到成功
找到合适的MTU
🎓 总结
MTU和MSS的关键点:
- MTU:链路层,整个包
- MSS:TCP层,只是数据
- 关系:MSS = MTU - 40
- 协商:三次握手时协商MSS
- 优化:避免分片,提高性能
记忆口诀:
MTU链路层定义 📡
MSS是TCP数据 📦
减去两个头部 ➖
得出实际大小 📏
三次握手协商 🤝
文档创建时间:2025-10-31