TCP 如何保证可靠传输,发生丢包时如何处理?
未标记
考查重点:字节序号、确认与重传。序号/ACK追字节,丢包超时/重复确认触重传,接收重排去重,流量与拥塞窗口限制发送
本题目录
参考答案
核心回答
TCP 在 IP 网络之上提供可靠、有序、无重复的字节流。它通过编号、确认、重传和接收端重排等机制恢复丢失的数据,并用流量控制、拥塞控制限制发送压力。
可以沿一段数据的发送过程来讲:
- 编号与校验:
TCP对字节流编号,报文段携带一段连续字节及其序号;校验和用于检测传输差错。序号不是“第几个业务消息”的编号。 - 确认与保留副本:接收端返回累计
ACK。ACK=N表示此前的连续数据已收到,下一步期待从 N 开始的字节。发送端保留尚未累计确认的数据,便于重传。 - 检测丢失并重传:发送端根据确认进度、重复
ACK、SACK和重传计时推断数据是否丢失。可以在满足快速恢复条件时提前重传,也有RTO超时重传兜底。 - 重排与去重:接收端根据序号处理乱序和重复数据,按顺序向应用交付。同一连接中的一次
TCP重传,不会因此变成应用再次收到同一段字节。 - 控制在途数据量:接收窗口
rwnd约束接收端承受能力,拥塞窗口cwnd约束向网络注入的数据量。恢复丢包时还要调整发送行为,避免越拥塞越猛发。
TCP 不能直接得知每次丢失的真实原因,而是根据反馈推断。丢包、乱序、ACK 丢失和延迟增大,都可能影响这些判断。
发生丢包后,具体怎样恢复?
超时重传:一直等不到确认时兜底
发送的数据迟迟没有获得确认,重传定时器到期后,发送端重传最早未确认的数据。RTO 根据平滑后的 RTT 和时延波动估计,发生超时后进行退避,不是固定等一个 RTT,也不是不停按同样频率重发。
ACK 自己也可能丢失。如果后续累计 ACK 已经覆盖了前面的字节,发送端就不必仅因为少了那一个 ACK 而重传;否则可能最终触发超时。收到重复数据时,接收端按序号去重并再次确认。
快速重传:有后续数据反馈时提前恢复
以 RFC 5681 的经典算法为例,发送端收到 3 个满足条件的重复 ACK,且中间没有推进累计确认位置的 ACK,就把相应缺口视为疑似丢失,不必等到 RTO 到期。
这里是“3 个重复 ACK”,不能简单数成“总共看到 3 次相同确认号”。重复 ACK 也可能由乱序等原因造成,并不是丢包的绝对证明。现代协议栈还可能采用 RACK 等基于时间和确认反馈的丢包检测,不能把经典计数规则当成所有实现的唯一算法。
SACK:告诉发送端哪些后续区间已经到了
例如发送三段字节 [1000,2000)、[2000,3000)、[3000,4000),中间一段没有到达,接收端已收到第一段和第三段。
累计 ACK 仍停在 2000。协商支持 SACK 时,接收端还可以报告 [3000,4000) 已收到,让发送端更准确地恢复缺口,减少不必要的重复发送。SACK 提供的是已接收区间信息,本身不等于“看到一个区间缺口就立即判定丢包”。
缺口补齐后,接收端便可推进累计确认,并继续按序交付后续字节。因此丢包常表现为延迟升高,后面即使有数据先到了,也可能暂时不能交给应用。
常见追问
流量控制和拥塞控制有什么区别?
前者针对接收方,后者针对网络承载能力。接收端来得及处理,不代表链路不拥塞;链路很空,也不代表接收应用及时读取。允许保持在途的未确认数据量受到两类窗口共同约束。慢开始、拥塞避免和恢复行为还取决于采用的拥塞控制算法,不能把所有实现都说成“丢包后窗口固定减半”。
TCP 可靠,为什么应用还需要消息 ID、确认和幂等?
TCP 不保留业务消息边界,上层仍要定义消息格式。TCP 的 ACK 确认字节传输,不代表应用已经完成订单处理或持久化。连接失败后,客户端也可能不知道此前请求是否执行成功;重连后再次发送是新的业务请求,仍可能重复执行,因此需要业务确认与幂等设计。
网络一直不通,会无限保证成功吗?
不会。连接可能因超时或复位而失败,具体失败条件和等待时间取决于协议栈与应用设置。应用应处理失败结果;TCP 的可靠传输能力不等于任意故障下都能完成一次业务操作。
参考资料
- 国内:JavaGuide:TCP 如何保证传输的可靠性?:采用序号、累计确认、RTO、快速重传、SACK 及两类窗口部分,把检测、补传与控制发送压力串起来。
- 国内:JavaGuide:TCP 面向字节流,UDP 面向报文:采用应用写入、网络分段和读取边界的解释,区分字节可靠、有序与业务消息完整处理。
- 国内:小林 coding:TCP 重传、滑动窗口、流量控制、拥塞控制:采用超时、快速重传、SACK 和累计确认的例子,解释确认丢失和数据缺口如何影响恢复;精确规则以 RFC 为准。
- 国外:IETF RFC 9293:Transmission Control Protocol:依据字节流服务、序号与确认、分段和连接失败条款,核对可靠性范围及其与应用读写边界的区别。
- 国外:IETF RFC 5681:TCP Congestion Control:依据 §3.1–§3.2 核对两类窗口、经典 3 个重复 ACK 触发条件,以及丢包恢复为何必须配合拥塞控制。
相关面经
12 篇字节跳动
AI 应用客户端开发实习生Tcp怎么保障可靠的
深信服
技术研发工程师 AI潜力麒麟软件
后端研发工程师TCP 是如何保证可靠传输的?
公司未注明
后端开发工程师TCP的确认重传机制是怎样的?如何应用到WebSocket的稳定性中?
水滴公司
AI全栈工程师说一下 TCP,它的特性是什么?



