“丢包重传”是网络通信中保障数据可靠传输的核心机制,简单说就是:发送方发现数据包在网络中丢失后,重新发送该数据包的过程。它是 TCP 等可靠传输协议的“兜底手段”。
下面按「为什么丢包 → 怎么发现丢包 → 怎么重传 → 有哪些策略」来讲清楚。
一、为什么会丢包?
网络不是“绝对靠谱的管道”,常见原因有:
- 网络拥塞:路由器/交换机缓存满了,被迫丢包
- 链路故障:Wi-Fi 信号差、网线松动、光纤中断
- 设备性能不足:网卡、路由器处理能力不够,队列溢出
- 传输错误:电磁干扰导致比特错误,被校验发现后直接丢弃
二、如何发现“丢包了”?
不同协议思路不同,典型的是 TCP 的做法:
1. 超时重传(Timeout Retransmission)
- 发送方发一个数据包后启动重传定时器
- 如果在规定时间内没收到 ACK(确认报文)
- 就认为这个包丢了,触发重传
关键参数:RTO(Retransmission Timeout)
- RTO 不能太长(影响速度),也不能太短(误判丢包)
- TCP 会根据 RTT(往返时间)动态计算 RTO
2. 快速重传(Fast Retransmit)
- 接收方收到“乱序报文”时,会连续发送重复的 ACK
- 比如:期待 Seq=100,却收到 Seq=200
- 于是反复回 ACK=100
- 发送方连续收到 3 个重复 ACK,不等超时就重传 Seq=100 的包
👉 这是 TCP 提升效率的关键优化。
三、重传是怎么进行的?
以 TCP 为例:
- 发送方维护一个发送窗口
- 每个发出去的数据包都携带序列号(Seq)
- 接收方按序列号确认(ACK)
- 一旦发现某个序列号没被确认:
- 要么超时触发重传
- 要么收到 3 个重复 ACK 触发快速重传
- 重传成功后,接收方 ACK 该序列号,窗口向前滑动
四、典型重传策略对比
| 策略 | 触发条件 | 优点 | 缺点 |
|---|---|---|---|
| 超时重传 | 定时器到期未收到 ACK | 实现简单,兜底可靠 | 等待时间长,延迟高 |
| 快速重传 | 连续 3 个重复 ACK | 响应快,减少等待 | 依赖重复 ACK,极端场景不适用 |
| 选择确认 SACK | ACK 中带 SACK 选项 | 可精确知道哪些段丢了 | 协议更复杂,需要两端支持 |
| FEC(前向纠错) | 不靠重传,靠冗余编码 | 实时性好,适合音视频 | 带宽开销大 |
注:SACK 常与快速重传配合使用,解决“只重传一个包但不知道到底丢了哪几个”的问题。
五、不同场景下的重传特点
1. TCP(可靠传输)
- 必做重传
- 有超时重传 + 快速重传 + SACK
- 重传会影响吞吐量、延迟,还会触发拥塞控制(如减半发送窗口)
2. UDP(不可靠传输)
- 默认不重传
- 需要可靠性的话,要在应用层自己实现:
- QUIC(HTTP/3 的基础)
- 游戏、实时音视频常用自定义重传策略
- WebRTC 中的 NACK(负反馈重传)
3. 应用层重传
- HTTP:浏览器/服务器在 TCP 之上,TCP 已经帮它做了重传
- 文件传输:强调可靠性,重传很关键
- 实时音视频:宁可丢包也不要高延迟,通常限制重传次数或干脆不用重传
六、重传带来的问题
- 延迟增加:尤其是超时重传,可能多等几十到几百毫秒
- 吞吐下降:重传会触发拥塞控制,降低发送速率
- 伪重传:因为 RTO 设得太小,包其实没丢,只是慢了一点,造成不必要的重传
七、一个直观的小例子
你在微信里发一条消息:
- TCP 把消息拆成多个包发送
- 其中一个包在路上丢了
- 手机没收到对应 ACK
- TCP 触发重传
- 最终所有包都到达,微信显示“已送达”
你感觉不到这个过程,但对网络来说,这就是一次典型的丢包重传。