📦 TCP重传机制:快递的"重发服务"

26 阅读4分钟

知识点编号:007
难度等级:⭐⭐⭐(必掌握)
面试频率:🔥🔥🔥🔥


🎯 一句话总结

重传就像快递丢了重发,TCP有两种:超时重发(慢)和快速重发(快)!


🤔 为什么需要重传?

网络不可靠:
发送:包1、包2、包3、包4、包5
接收:包1、包2、❌、包4、包5
       (包3丢了!)

解决:重传机制
检测到包3丢失 → 重新发送包3

🎭 两种重传机制

1. 超时重传(Timeout Retransmission)⏰

原理:设置定时器,超时未收到ACK就重传

过程:
发送方:发送包3,启动定时器⏰
接收方:(包丢了,没收到)
发送方:⏰时间到了,还没收到ACK3
发送方:重传包3

超时时间(RTO)计算:
RTO = RTT + 4 × RTT偏差
RTT:往返时间
RTO:重传超时时间

示例:
RTT = 100ms
RTO ≈ 200ms

缺点:
- 等待时间长
- 效率低

生活例子:
寄快递,约定3天到
3天后还没到,重新寄一份

2. 快速重传(Fast Retransmit)⚡

原理:收到3个重复ACK,立即重传

过程:
发送:包1、包2、包3、包4、包5
接收:包1、包2、❌、包4、包5

接收方:
收到包1 → 发送ACK1 ✅
收到包2 → 发送ACK2 ✅
期待包3,但收到包4 → 发送ACK2 ⚠️(重复)
期待包3,但收到包5 → 发送ACK2 ⚠️(重复)

发送方:
收到ACK1 ✅
收到ACK2 ✅
收到ACK2(重复1次)
收到ACK2(重复2次)
收到ACK2(重复3次)⚡
立即重传包3!(不等超时)

优点:
- 无需等待超时
- 快速恢复
- 效率高

生活例子:
你:"听到了吗?"1)
朋友:"啊?"2)
朋友:"啊?"3)
朋友:"啊?"4)← 第3"啊?"
你立刻重复:"听到了吗?!"

📊 对比

特性超时重传快速重传
触发条件超时3个重复ACK
等待时间长(RTO)
效率
适用场景包彻底丢失包乱序或部分丢失

💻 Java代码示例

设置超时时间

Socket socket = new Socket();
socket.connect(
    new InetSocketAddress("localhost", 8080),
    5000  // 连接超时5秒
);

// 设置读取超时
socket.setSoTimeout(10000); // 10秒

try {
    InputStream in = socket.getInputStream();
    byte[] buffer = new byte[1024];
    int len = in.read(buffer); // 10秒内收不到数据会抛异常
} catch (SocketTimeoutException e) {
    System.out.println("超时!触发重传...");
    // TCP层会自动重传
}

观察重传

# 使用tcpdump观察重传
tcpdump -i any port 8080 -nn

# 输出示例:
# 12:00:00.000 IP 192.168.1.1.50000 > 192.168.1.2.8080: ... seq 1:100
# 12:00:00.500 IP 192.168.1.1.50000 > 192.168.1.2.8080: ... seq 1:100
#                                                         ↑ 重传(seq相同)

# 或使用Wireshark,过滤器:
# tcp.analysis.retransmission

🐛 常见面试题

Q1:TCP的两种重传机制是什么?

答案:

1. 超时重传(Timeout Retransmission)
   触发:发送后超过RTO时间未收到ACK
   特点:
   - 等待时间长
   - 适用于包彻底丢失
   - 超时时间动态计算(基于RTT)

2. 快速重传(Fast Retransmit)
   触发:收到3个重复的ACK
   特点:
   - 不等超时,立即重传
   - 速度快,效率高
   - 适用于包乱序或少量丢包

对比:
快速重传比超时重传快得多
通常先尝试快速重传
如果不行再用超时重传

Q2:为什么是3个重复ACK触发快速重传?

答案:

为什么不是1个或2个?

1个重复ACK:
- 可能只是包乱序
- 不一定是丢包
- 立即重传太激进

2个重复ACK:
- 还不确定是否真的丢包
- 可能还在路上

3个重复ACK:
- 基本确定包丢了
- 平衡了检测速度和准确性
- 实践证明效果好

示例:
发送:1, 2, 3, 4, 5
到达:1, 2, 4, 3, 5(乱序)

接收方:
收到1 → ACK1
收到2 → ACK2
收到4(期待3)→ ACK2(1次重复)
收到3(终于到了)→ ACK3
收到5 → ACK5

这种情况不会触发快速重传(只有1个重复ACK)
包只是乱序,不是丢失

如果真的丢了:
发送:1, 2, 3, 4, 5, 6
到达:1, 2, ❌, 4, 5, 6

接收方:
收到1 → ACK1
收到2 → ACK2
收到4 → ACK2(1次重复)
收到5 → ACK2(2次重复)
收到6 → ACK2(3次重复)⚡ 触发快速重传

🎓 总结

TCP重传的关键点:

  1. 超时重传:等RTO时间,慢但可靠
  2. 快速重传:3个重复ACK,快速高效
  3. 选择:优先快速重传,不行再超时重传

记忆口诀

超时重传等RTO ⏰
快速重传三重复 ⚡
两种机制保可靠 ✅
TCP传输不丢包 📦

文档创建时间:2025-10-31
作者:AI助手 🤖