Skip to content

模块导航: 总入口 · 总纲与方法 · 后端场景 · AI与算法工程 · 国企与金融 · 网络问答


4. TCP 如何保证可靠传输(热度 310 · 高频选考) ​

Q: TCP 靠什么机制保证可靠?

A:

机制全景(四件套 + 两把窗口) ​

可靠性目标:数据无差错、不丢失、不重复、按序到达。

  1. 序号与确认(seq/ack)

    • 每个字节都有序号;报文段首部 Sequence Number 是本报文数据的首字节序号。
    • 接收方用累积确认:ack=N 表示「N 之前的所有字节都已正确收到,期望下次从 N 开始」。
    • TCP 对数据字节编号,不是「第几个包」。
  2. 超时重传(Retransmission Timeout)

    • 每个报文段有关联 RTO 定时器;超时未确认则重传。
    • RTO 由 RTT 动态估算:SRTT ← (1-α)SRTT + α*SampleRTT,RTO = SRTT + 4*RTTVAR。
    • Karn 算法: 重传的 RTT 样本不可信(无法区分是对原包还是重传包的确认),要排除;RTO 退避(倍增)。
  3. 快速重传

    • 连续收到 3 个重复 ACK 立即重传丢失段,不等超时。
    • 省下的是整个 RTO 等待,不是"一个 RTT":凑齐 3 个重复 ACK 本身约要 1 个 RTT,而走超时路径要等 RTO —— 本机内核 include/net/tcp.h 里 TCP_RTO_MIN = HZ/5(CONFIG_HZ=1000 → 200ms 下界),初始 RTO TCP_TIMEOUT_INIT = 1*HZ(1s,RFC 6298 §2.1 的初始值 1s),上界 TCP_RTO_MAX = 120*HZ(120s)。所以快重传把重传时延从数百毫秒~秒级压到 RTT 级,这才是它的收益量级。
    • 重复 ACK 的含义:「我期望序号 X,但收到了 X 之后的数据」——中间有洞。
  4. 校验和

    • 首部 + 数据的 16 位校验(含伪首部),检出比特错误则丢弃(等待重传)。
  5. 流量控制(rwnd)——面向接收方

    • 接收方在 ACK 中通告窗口字段:「我还能收多少字节」。
    • 接收缓冲区满 → 通告 0 窗口;发送方启动零窗口探测定时器。
  6. 拥塞控制(cwnd)——面向网络

    • 根据网络拥塞程度调整发送速率(见第 6 题)。
    • 实际发送窗口 = min(rwnd, cwnd)。
  7. 补充机制(深化)

    • 乱序缓存: TCP 收到乱序段不丢弃,缓存并回重复 ACK 催缺口(更像 SR 而非 GBN)。
    • 去重: 接收端按序号去重。
    • 保活与 RST: 异常时用 RST 复位连接。

设计动机 ​

  • 为什么用累积确认而不是每包单独确认? 减少 ACK 数量、简化实现;配合快速重传与 SACK 可减轻「累计确认带来的模糊性」。
  • 为什么快速重传门限是 3? 1 个重复 ACK 可能是乱序;连续 3 个说明后续多个包都到了但中间缺一块,更确信是丢包。
  • 区分「可靠传输」与「拥塞控制」: 可靠面向接收方交付正确性;拥塞面向网络不被打垮。两者机制独立、最终窗口取 min。

常见追问 ​

追问 1:TCP 收到乱序包会丢弃吗?和 GBN 什么关系?

  • 答题要点: 不丢弃,缓存乱序段并发送重复 ACK,促使发送方快速重传缺口。更像选择重传 SR,而不是「丢弃一切乱序」的 GBN。笔试若问 GBN/SR 窗口上限是另一套题(补-03/04)。

追问 2:SACK 是什么?解决什么问题?

  • 答题要点: Selective Acknowledgment,TCP 选项。接收方在 ACK 中告诉发送方「哪些非连续块已收到」,发送方只重传缺失段,避免累计确认导致的重复发送。需要双方协商开启。

追问 3:可靠传输 = 100% 不丢数据吗?

  • 答题要点: TCP 提供的是在连接存续期间、网络最终能恢复的前提下的可靠字节流。若网络长期中断、应用崩溃、连接被 RST,仍可能失败。可靠性是传输层协议语义,不是分布式系统级的端到端 exactly-once。

易错点 ​

易错说法纠正
「ACK 确认的是包不是字节」TCP 对字节编号,ACK 是期望序号(累积)
「可靠传输=拥塞控制」可靠侧重序号/重传/校验;拥塞控制侧重网络速率,发送窗口取两者 min
「超时与快速重传窗口变化一样」超时:cwnd 回 1 重新慢开始;快速重传触发快恢复:cwnd 降到约一半
「TCP 从不缓存乱序」会缓存,配合重复 ACK / SACK
「校验和能纠错」只检错;纠错靠重传

与选择题对照 ​

  • 主库 150: 第 59 题(端到端可靠传输)、第 66 题(流量控制目的)、第 67 题(发送窗口取决于)、第 68 题(3 个重复 ACK)、第 69 题(超时重传后 cwnd)、第 78 题(乱序报文段处理)、第 121 题(TCP/UDP 对比)。
  • 补题 16: 补-03(GBN 窗口上限)、补-04(SR 窗口上限)、补-11(TCP 首部)。
  • 口述联动: 选择题「乱序会怎样」答「缓存+重复 ACK」,与本题可靠传输机制直接衔接。

工程 / 抓包背景 ​

  • Wireshark: tcp.analysis.duplicate_ack、tcp.analysis.retransmission、tcp.analysis.out_of_order、tcp.options.sack。
  • ss: ss -tin 可看到 rtt、cwnd、retrans、snd_wnd 等 TCP 内部信息;注意 iproute2 没有名为 rwnd 的字段——「对端通告的接收窗口」在这里叫 snd_wnd(uapi tcpi_snd_wnd 注释即 "peer's advertised receive window after scaling"),本端接收侧则是 rcv_space/rcv_ssthresh;当发送被对端窗口卡住时还会多一个 rwnd_limited:<ms>。
  • sysctl: net.ipv4.tcp_sack、net.ipv4.tcp_timestamps、net.ipv4.tcp_rmem/tcp_wmem。
  • 现象: 大量 retransmission + RTT 抖动 → 网络丢包/缓冲膨胀;SACK 块多 → 非连续丢包;零窗口 → 接收方处理不过来(应用层消费慢)。

持续学习,持续积累。