TCP 重传与超时:可靠性是怎么保证的
更新时间:2026-09-17。网络协议域·传输层。可靠性要和"发多快"的拥塞控制区分开:本篇讲丢包后怎么补,发多快见 TCP 拥塞控制。
TCP 给字节流的每个字节编号(序列号),接收方回 ACK 告诉发送方"我已连续收到第几号之前"。发送方发出的数据先放进重传队列,在被确认前一直留着;一旦判定丢了,就重传。判定丢失有两条路径:超时与快速重传。
一、超时重传(RTO)
发送方为每个已发未确认的段启动一个重传定时器(RTO,Retransmission Timeout):
- RTO 不是拍脑袋的固定值,而是根据实测 RTT 动态计算的(经典 Jacobson 算法:用平滑 RTT 的均值 SRTT 与偏差 RTTVAR 估算,RTO = SRTT + 4·RTTVAR),既不能太短导致正常延迟被误判丢包,也不能太长导致恢复太慢。
- 超时后重传该段,并把 RTO 指数退避(×2、×4…),同时拥塞控制进入慢启动(超时通常被当作严重拥塞信号)。
RTT 抖动大的网络(移动、跨洲)RTO 被撑大,真丢包时恢复慢;而 RTO 设过小又会在高延迟链路上误重传。Linux 有
tcp_early_retrans、RACK(基于到达时间而非纯重复 ACK 判定丢包)等改进。
二、快速重传:不必干等超时
如果发送方连续收到 3 个重复 ACK(即 4 个相同确认号:1 个原始 + 3 个 dup ACK),就推断中间那个段丢了,立即重传而不等 RTO 到期:
发送: 1 2 3 4 5
3 丢了,接收方收到 4、5 时都只能 ACK "期待 3"
ACK: ack2 ack3? 实际连续回 ack=3 三次(dup ACK)
发送方收到第 3 个 dup ACK -> 立即重传 seg 3- 为什么是 3 个:单个/两个重复 ACK 可能只是乱序而非丢包,用 3 作为"乱序一般不会这么严重"的经验阈值,降低误判。
- 快速重传通常配合快速恢复:把拥塞窗口减半、进入恢复而非直接退回慢启动(重复 ACK 说明后续包其实到达了,网络没那么糟)。
- RACK 现代算法用"更高序号的包都已 ACK,唯独某个旧段没被确认"的时间关系来判丢,比固定 3 dup ACK 更准,能处理乱序重排。
三、SACK:选择性确认
经典累计 ACK 只说"3 之前都收到",发送方不知道 4、5 其实也到了,可能盲目重传已收到的数据。**SACK(Selective ACK)**让接收方在 ACK 选项里附带"还收到了哪些不连续区间":
ACK: ack=3; SACK: 4-6 (3 丢了,但 4、5 已到)发送方据此只重传真正缺失的段,减少无效重传,在丢包率高、乱序的网络里收益明显。相关扩展还有 D-SACK(重复 SACK,能检测出"其实没丢却被重传"的假丢包,用于调 RACK 乱序阈值)。
四、怎么看重传
nstat -az | grep -i 'TcpRetrans\|TcpTimeout\|TCPRTC' # 系统级重传计数
ss -ti '( dport = :443 )' # 单连接:rtt、rto、retrans、cwnd
nstat -az | grep -i 'tcpext' # 含 TCPLostRetransmit 等
netstat -s | grep -i 'retrans' # 传统接口ss -ti 关键字段:rtt:0.8/0.2(均值/偏差 ms)、rto:204、retrans:3/12(重传次数/最近超时相关)、cwnd、bytes_retrans。
怎么看重传率:
TcpExtTCPRetransSegs / TcpOutSegs的比例。健康数据中心通常远低于 0.1%;公网、移动网络、拥塞链路会高一些。重传持续高说明真实丢包(线路、队列溢出、限速)或中间设备问题,应用层会表现为延迟毛刺——重传是把"丢包"转成"延迟"。区分丢包与带宽不足可结合tc弱网与抓包。
五、和流控、拥塞控制的关系
| 机制 | 解决的问题 | 信号 |
|---|---|---|
| 重传(本篇) | 包丢了怎么补 | RTO 超时 / 3 dup ACK / RACK |
| 流量控制 | 接收方收不下 | 接收窗口 rwnd(见滑动窗口篇) |
| 拥塞控制 | 网络发太快 | 丢包/ECN/RTT,调 cwnd |
可靠性(重传、序号、校验和)与流量控制、拥塞控制共同构成 TCP"在不可靠 IP 之上提供可靠字节流"的三大支柱。
相关阅读
总结
TCP 靠序列号+累计确认保证可靠:丢包先等基于 RTT 动态估算的 RTO 超时重传(超时退避并回慢启动),收到 3 个重复 ACK 则快速重传并快速恢复,SACK 让发送方只补真正缺失的段;用 nstat/ss -ti 看 retrans 计数与重传率,重传把丢包转化为延迟、是延迟毛刺的常见来源。