网络基础12 分钟阅读更新于 2026-07-30

TCP 重传机制:数据丢了、ACK 丢了,为什么还能补回来

围绕TCP 重传机制章节,讲清序号、确认号、发送缓冲区、RTO 超时重传、重复 ACK、快速重传和快速恢复。

相关工具

可靠不是不丢,而是能发现并补上

很多人说 TCP 可靠,容易误解成“TCP 传输过程中不会丢包”。真实网络里,数据段可能丢失,ACK 也可能丢失,路由器队列可能溢出,链路也可能抖动。TCP 的可靠性,不是保证问题不发生,而是尽量发现问题,并把缺失的数据补回来。

资料 在 TCP 重传机制里说,当发送方的数据在传输过程中丢失、损坏或延迟,接收方可以请求发送方重新传输这些数据。实现这个能力,离不开序号、确认号、发送窗口、接收窗口、定时器和重传策略。

先记住一句话:TCP 传的是有序字节流。每个字节都有位置,接收方通过确认号告诉发送方“我已经连续收到哪里了,下一段从哪里开始发给我”。只要这个坐标系在,TCP 就能判断哪些数据已确认、哪些数据可能丢了、哪些数据需要重新发送。

序号和确认号是重传的基础

已有内容提到,在 TCP 通信中,每个发送的字节都有唯一序号,每个接收的字节都有确认号。比如发送方发出一段数据,序号从 1001 开始,长度 1000 字节,那么接收方完整收到后,可以返回 `ACK=2001`,意思是 2001 之前的字节我都连续收到了。

这里的确认号不是简单说“收到这个包”,而是说“下一个期望收到的字节序号”。这让 TCP 可以处理乱序、重复和丢失。收到重复数据时,接收方可以根据序号判断它已经处理过,不会把同一段字节重复交给上层。

发送方也会把未确认的数据保留在发送缓冲区里。数据发出后不能马上丢掉,因为还没确认它真的到达。如果超时没有收到 ACK,或者收到重复 ACK 暗示中间缺了一段,发送方就从缓冲区里取出对应数据重新发送。

超时重传:等不到 ACK 就补发

资料 对超时检测的描述是:发送方为每个发送的数据段设置一个定时器,定时器时长称为超时时间。如果在超时时间内没有收到确认,发送方会认为数据丢失或损坏,触发重传。

最直观的情况是数据段丢了。发送方发出一段数据,网络中间把它弄丢了,接收方根本没收到,自然不会返回对应 ACK。发送方等到重传超时时间 RTO 到了,还没拿到确认,就重新发送同一段数据。

另一种情况是数据到了,但 ACK 丢了。接收方其实已经收到数据,也返回了 ACK,只是 ACK 在路上丢了。发送方看不到 ACK,也会超时重传。接收方再次收到这段相同序号的数据后,会识别为重复数据,丢弃重复内容,再返回 ACK。这就是为什么 TCP 重传不等于业务重复处理。

TCP 超时重传机制中文流程图,展示数据段丢失、ACK 丢失、RTO 定时器、重传和接收方按序号去重
TCP 超时重传机制

发送方为未确认数据启动 RTO 定时器。数据段丢失或 ACK 丢失时,发送方等不到确认会重传,接收方通过序号去重。

RTO 不能太短,也不能太长

超时重传听起来简单,但 RTO 设置很讲究。太短会误判。网络只是稍微慢一点,ACK 还在路上,发送方就提前重传,造成额外流量。太长又会恢复太慢,数据真丢了也要等很久,用户看到的就是卡顿。

实际 TCP 会根据往返时间 RTT 的估计动态调整 RTO。路径延迟稳定时,RTO 可以相对贴近真实 RTT;路径抖动大时,RTO 要留出余量,避免频繁误重传。我们不需要在应用层手动算这些,但排查网络问题时要知道:超时重传往往意味着 ACK 在合理等待时间内没有回来。

如果抓包里看到大量 Retransmission,不一定马上说明源站坏了。它可能是链路丢包,可能是跨地域 RTT 抖动,也可能是接收端迟迟不确认。要结合 RTT、窗口大小、重复 ACK 和网络路径一起看。

重复 ACK:接收方在说我还缺这一段

超时重传要等定时器,有时太慢。文中提到快速重传策略:当接收方连续接收到相同确认号时,它会立即向发送方发送冗余确认,以触发发送方进行重传。

举个例子,发送方连续发出 Seq=1、2、3、4、5,其中 Seq=2 丢了,Seq=3、4、5 都到了。接收方已经收到 1,所以会确认 ACK=2,表示下一段想要 2。后来 3、4、5 虽然到了,但中间缺了 2,接收方不能按序交付,只能继续返回 ACK=2。

发送方连续看到多个 ACK=2,就能推断:接收方不是没收到任何数据,而是一直在等 2。于是发送方不必等 RTO 超时,直接重传 Seq=2。这就是快速重传。

快速重传比超时重传更早发现丢包

快速重传的好处,是把等待时间缩短了。只要后续数据还能到达接收方,接收方就会不断反馈重复 ACK。发送方从这些重复 ACK 里看到缺口,能更早补上丢失的数据段。

这也说明快速重传依赖一个前提:丢的不是最后一段,后面还有数据到达接收方。如果发送方只发了一段数据,它丢了,接收方没有任何后续数据可触发重复 ACK,发送方还是只能等超时。

因此,超时重传和快速重传不是谁替代谁。超时重传是兜底,快速重传是更快的发现方式。网络状况不同、丢包位置不同,触发路径也会不同。

TCP 快速重传与重复 ACK 中文流程图,展示 Seq=2 丢失、接收方重复 ACK=2、发送方触发快速重传并最终按序交付
TCP 快速重传与重复 ACK

当中间某段丢失但后续数据到达时,接收方会重复确认缺失序号。发送方收到多个重复 ACK 后,不等超时就重传缺失段。

快速恢复会配合重传一起降速

资料 在快速重传后还提到快速恢复。发送方接收到快速重传的确认后,不需要等到超时再次发送,而是可以使用快速恢复算法继续发送未丢失的数据。它和拥塞控制联系很紧。

因为丢包通常意味着网络可能拥塞,发送方不能补发完丢失段后继续按原速度猛发。快速恢复会把拥塞窗口降下来,但不会像超时那样完全退回到最小窗口。原因是重复 ACK 说明网络还在传输后续数据,情况没有超时那么严重。

所以一条 TCP 连接遇到丢包后,既要把缺失的数据补上,也要把发送节奏调低一点。重传解决可靠性,快速恢复解决恢复过程中的拥塞控制。

重传策略不是简单全量重发

文中说,如果只有一个数据段丢失,发送方只会重传丢失的数据段;如果多个数据段丢失,发送方可能会使用更复杂的算法决定哪些数据需要重传。这一点很重要。

TCP 不会因为一个字节丢了,就把整个文件从头再发。它根据序号、确认号和接收方反馈定位缺失范围。确认过的数据不用再发,未确认或被判断丢失的数据才需要重传。这样才能在保证可靠的同时,尽量减少重复流量。

实际协议栈还可能使用选择性确认 SACK 等机制,让接收方告诉发送方哪些不连续的数据块已经收到。这样发送方能更准确地补缺口。即使不展开这些细节,也要理解方向:TCP 的重传是按字节序号和确认状态精细处理的。

重传不等于应用层幂等

这里有个工程上很容易混的问题:TCP 重传和业务重试不是一回事。TCP 重传发生在传输层,重发的是相同字节流里的某一段。接收方 TCP 栈会根据序号去重,保证上层应用按顺序看到一份数据。

业务重试发生在应用层。比如客户端超时后又发了一次下单请求,服务端可能真的收到两次完整 HTTP 请求。这时 TCP 不会替你判断这两个请求是不是同一笔订单。业务层必须用请求 ID、订单号、幂等键等机制处理。

所以不要因为“TCP 是可靠的”就忽略接口幂等。TCP 保证的是字节流可靠交付,不保证业务操作只执行一次。支付、下单、扣库存、发券这些操作,仍然要在业务层设计幂等。

排查时怎么看重传

抓包工具里看到 TCP Retransmission,先看它是偶发还是持续。偶发重传在复杂网络里并不少见,尤其跨地域、弱网、无线网络下更常见。持续大量重传才需要重点排查链路质量、丢包、拥塞和接收端状态。

再看是超时重传还是快速重传。超时重传通常等待时间更长,说明 ACK 在 RTO 内没有回来;快速重传会伴随多个重复 ACK,说明后续数据还能到达,只是中间缺了一段。两者对应的网络状态不完全一样。

最后结合窗口和 RTT。接收窗口很小,可能是接收端处理慢;RTT 抖动大、重复 ACK 多、重传多,可能是网络拥塞或丢包;如果只有某个路径有问题,就看运营商、跨机房、代理和防火墙设备。

面试里怎么讲

如果被问 TCP 重传机制,可以先说基础:TCP 给字节编号,用确认号表示接收方下一步期望收到的字节。发送方把未确认数据保存在发送缓冲区,并为其启动重传定时器。

然后讲超时重传:如果在 RTO 内没有收到 ACK,发送方认为数据或 ACK 可能丢失,就重传对应数据段。接收方如果收到重复数据,会根据序号去重,不会把重复内容交给上层应用重复处理。

最后讲快速重传:如果接收方收到后续乱序数据,会重复确认缺失的序号;发送方收到多个重复 ACK 后,可以不等超时,立即重传缺失段。快速恢复会配合降低拥塞窗口,让连接更平滑地从丢包中恢复。

常见问题

TCP 重传会不会导致应用收到重复数据?

正常不会。TCP 接收端会根据序号识别重复数据,并按顺序把字节流交给上层。业务层看到的通常是一份有序数据,而不是重复 TCP 段。

快速重传为什么需要重复 ACK?

重复 ACK 表示接收方一直在等待同一个序号,通常说明中间某段丢了但后续数据到了。发送方据此可以提前重传缺失段,不必等 RTO 超时。

TCP 可靠了,业务接口还需要幂等吗?

需要。TCP 可靠的是字节流传输,不保证业务请求只执行一次。客户端应用层重试可能产生多次完整请求,下单、支付、扣库存等操作仍要设计幂等。

计算机网络

继续阅读

返回专题