408 知识网络
返回模块节点

CN-4 传输层(TCP 可靠传输与拥塞控制)

计算机网络

来源:40-CN4-传输层.md · 完整笔记(7 节,未删减)

计算机网络模块。对应全局地图高频因果链第 5 条(TCP 可靠与拥塞链)。 计网大题与选择题的绝对核心(TCP ★★★★★,来源:复习资料 P5 §1.4)。


核心问题

这一部分为什么存在?

网络层(IP)只解决“把分组送到目的主机”,而且是不可靠的:可能丢包、乱序、重复。但应用程序真正需要的是:

  1. 进程到进程的通信——一台主机上跑着浏览器、邮件、FTP,分组到了主机该交给谁?→ 需要端口。
  2. 可靠的字节流——应用不想自己处理丢包乱序 → 需要序号、确认、重传。
  3. 不把对方淹死——发送方快、接收方慢 → 需要流量控制。
  4. 不把网络搞垮——所有主机都拼命发,路由器缓存溢出、全网崩溃 → 需要拥塞控制。

四个需求层层递进,构成本模块的主线。第 4 条尤其关键:流量控制只盯着接收方,拥塞控制盯着整个网络——接收方缓存再大,路由器队列满了照样丢包,所以仅有流量控制不够(这正是用户要求理解的“为什么”)。

如果没有传输层:每个应用都要自己实现可靠性(重复造轮子且互相不兼容),并且大量应用无节制发包会造成拥塞崩溃(congestion collapse)——吞吐率趋近于零。


概念体系

flowchart TD
    A["IP 只到主机且不可靠"] --> B["端口:定位到进程<br/>UDP/TCP 复用与分用"]
    A --> C["可靠性三件套<br/>序号 + 确认(ACK) + 超时重传"]
    C --> D["连接管理<br/>三次握手 / 四次挥手"]
    C --> E["流量控制<br/>rwnd 约束发送方:别把接收方淹死"]
    C --> F["拥塞控制<br/>cwnd 约束发送方:别把网络搞垮"]
    E --> G["发送窗口 = min(cwnd, rwnd)"]
    F --> G
    F --> H["慢开始 → 拥塞避免<br/>→ 快重传 / 快恢复"]

核心概念:

概念 是什么 约束谁 易考点
端口 16 位,标识主机上的应用进程 UDP 分用依据目的端口号(2018 年 39 题)
序号 seq 段中第一个数据字节的字节流编号 SYN、FIN 各占 1 个序号
确认号 ack 期望收到的下一个字节序号 = 已连续正确收到的最后字节 + 1 累计确认:ack=N 表示 N 之前全部收到
rwnd 接收窗口 接收方通告的剩余缓存 发送方(流量控制) 乙不取走数据时 rwnd 逐段减小(2015 年 39 题)
cwnd 拥塞窗口 发送方根据网络拥塞程度自行维护 发送方(拥塞控制) 发送窗口 = min(cwnd, rwnd)
ssthresh 慢开始门限 慢开始与拥塞避免的分界 cwnd 的增长方式 超时/3 重复 ACK 时 = 当前 cwnd/2
RTT / RTO 往返时间 / 超时重传时间 重传计时器 超时 = 拥塞的严重信号

实现机制

1. UDP:为什么“不可靠”还有人用

UDP 只加了端口和校验和(8B 首部),不建立连接、不确认、不重传。价值在于:低时延(无握手)、无连接状态、可广播/组播、首部开销小——适合 DNS 查询、实时音视频、SNMP 等“快比全重要”的场景。对比题:12B 数据用 UDP(首部 8B)效率 12/20 = 60%,用 TCP(首部 20B)效率 12/32 = 37.5%(2021 年 39 题)。UDP 校验和计算含伪首部(2024 年 39 题考二进制校验和计算)。

2. 可靠传输三件套(TCP 的地基)

  • 按字节编序号:应用看到的是无边界的字节流,seq 标记每段数据在流中的位置。
  • 累计确认 + 捎带确认:ack = N 表示“N 之前都收到了”;确认通常搭在反向数据段上。
  • 超时重传:每发一段启动计时器,RTO 到期未确认则重传。

经典考题逻辑:甲发 300B、400B、500B 三段,第 3 段序号 900,乙只正确收到第 1、3 段 → 先反推各段序号:第 2 段 = 900 − 400 = 500,第 1 段 = 500 − 300 = 200;乙连续正确接收的字节止于 499(第 2 段是空洞,第 3 段虽收到也不能计入),故确认号 = 500(2011 年 40 题)。陷阱:确认号永远指向“连续正确接收的下一字节”,乱序收到的段不能计入。

3. 连接管理:为什么三次、为什么四次

三次握手SYN(seq=x) → SYN+ACK(seq=y, ack=x+1) → ACK(ack=y+1)

  • 为什么不是两次:为了防止已失效的连接请求突然到达——若两次即建立,一个迟到的旧 SYN 会让服务器白白建立连接并等待数据,浪费资源;第三次握手让客户端确认“这次连接是我现在要的”。同时双方要互相确认对方的初始序号(两次握手服务器无法确认客户端收到了自己的 y)。
  • 考法:已知双方初始序号 2018、2046,第三次握手的确认号 = 2046+1 = 2047(2019 年 39 题);第二次握手 SYN=1、ACK=1,ack = 客户端 ISN + 1(2016 年 41 题第 1 问)。

四次挥手FIN → ACK → FIN → ACK

  • 为什么四次而握手三次:TCP 全双工,两个方向要分别关闭;被动方收到 FIN 时可能还有数据没发完,只能先回 ACK(“我知道你要关了”),等数据发完再发自己的 FIN——ACK 与 FIN 不能合并,所以多一次。
  • FIN 占 1 个序号:SYN 序号 1000、FIN 序号 5001 且无重传 → 数据字节 = 5001 − 1001 = 4000B(2020 年 39 题)。

4. 流量控制:rwnd 怎么约束发送方

接收方在每个 ACK 中通告 rwnd = 接收缓存剩余量。发送方保证:已发未确认的字节数 ≤ min(cwnd, rwnd)

  • 2010 年 39 题:cwnd=4000B,连发两段共 2000B,收到对第一段的确认且通告 rwnd=2000 → 还可发 = min(4000, 2000) − 已发未确认 1000 = 1000B
  • 2015 年 39 题(重要变体):乙的 16KB 缓存只存不取 → rwnd 随每段到达递减:初始通告 16KB,甲慢开始 1→2→4→8 KB,第 4 个 RTT 后已发 15KB,rwnd 只剩 1KB → 发送窗口 = 1KB。cwnd 还在涨,但 rwnd 先见底——两个窗口谁小谁说了算

5. 拥塞控制:四种机制的因果链

为什么流控不够:rwnd 只反映接收方缓存,网络中间路由器的队列状态没人告诉发送方;所有发送方都按 rwnd 上限猛发 → 路由器队列溢出丢包 → 超时重传进一步加重负担 → 恶性循环。所以发送方必须自己探测网络的承受能力(cwnd),这是端到端探测:丢包(超时/重复 ACK)被当作拥塞信号。

  • 慢开始:cwnd 从 1 MSS 起,每收到一个 ACK 就 +1 MSS,效果是每 RTT 翻倍(1→2→4→8…)。为什么指数:连接刚建立时对网络一无所知,指数增长是“快速爬坡、尽快接近可用带宽”的最优策略;但指数增长不能无限制 →
  • ssthresh 门限:cwnd ≥ ssthresh 后转拥塞避免,每 RTT 只 +1 MSS(加法增大,谨慎逼近极限)。
  • 超时(严重信号:可能整段路径出问题):ssthresh ← cwnd/2,cwnd ← 1,退回慢开始(保守重来)。
  • 三个重复 ACK(轻度信号:只丢了个别段,网络仍通——否则后续段到不了、收不到重复 ACK):快重传(立即重传丢失段不等超时)+ 快恢复:ssthresh ← cwnd/2,cwnd ← ssthresh(而非 1),直接进入拥塞避免。为什么减半而不归零:重复 ACK 证明网络仍在投递分组,没必要从头探测。

两类事件不同处理是最高频考点:

事件 网络状况推断 ssthresh cwnd 之后
超时 严重拥塞 cwnd/2 1 MSS 慢开始
3 个重复 ACK 轻度丢包 cwnd/2 ssthresh(减半) 拥塞避免

计算模板(来源:复习资料 P5 模板 8):MSS=1KB,cwnd=16KB 超时 → ssthresh=8、cwnd=1;慢开始 1→2→4→8 用 3 RTT,拥塞避免 8→16 用 8 RTT,共 11 RTT(2022 年 38 题;2009 年 39 题同型:16KB 超时后 4 RTT → cwnd=9KB)。


方案比较

TCP vs UDP(为什么易混 / 怎么选):都走端口、都属传输层。本质区别:TCP 用连接状态换取可靠、有序、流量与拥塞控制;UDP 用放弃这些换取简单与低时延。判别线索:题目出现“DNS 查询/实时性/广播”→ UDP;“文件传输/网页/邮件”→ TCP。效率题直接算首部比(2021 年 39 题)。

流量控制 vs 拥塞控制(本模块第一易混对):为什么易混——都通过限制发送窗口实现,公式里还取 min。本质区别——流量控制是点对点问题(保护接收方缓存,信息来自对方显式通告),拥塞控制是全局问题(保护网络,信息来自发送方对丢包的隐式推断)。判别线索:题目给“接收缓存/rwnd 通告”→ 流量控制(2015-39);给“超时/重复 ACK/ssthresh”→ 拥塞控制(2022-38)。

TCP 可靠机制 vs 链路层 GBN/SR(X-6 连接点):同一套滑动窗口思想的两层实例。差别:链路层按编号、在单条链路上;TCP 按字节编号、端到端跨多跳;TCP 的重传计时器需自适应 RTT 变化,链路层 RTT 基本固定。窗口约束公式也不同:GBN W2n1W \leq 2^n - 1,SR(收发等窗)W2n1W \leq 2^{n-1}


应用与考法

形态一:序号与确认号计算(必考):2009-38(确认号=首序号+载荷总长)、2011-40(乱序到达时累计确认指向连续末尾+1)、2013-39(由对方段推己方 seq/ack)、2019-39(握手确认号)、2020-39(由 SYN/FIN 序号推数据量)、2021-40(由 ack+rcvwnd 定可发序号范围 501~1000)、2024-47(FTP 数据连接序号与挥手 ACK 综合)。

形态二:窗口联合计算(发送窗口 = min(cwnd, rwnd)):2010-39、2014-38(超时后 10 RTT,发送窗口 10KB)、2015-39(缓存不取走,rwnd 衰减到 1KB)、2020-38(无拥塞时 cwnd 8→32KB 最长 48ms:拥塞避免最慢)。

形态三:拥塞控制曲线/事件分析:2009-39、2022-38(超时回 1,11 RTT 恢复 16KB)、2016-41(大题:三次握手标志位 + rwnd 递减 + 发送窗口降为 0 的时刻与平均速率)、2024-47(ssthresh=4MSS 时按确认号推 cwnd)。

形态四:UDP 辨析:2014-39(UDP 叙述正误)、2018-39(分用依据目的端口)、2021-39(载荷效率 60% vs 37.5%)、2024-39(UDP 校验和计算)。

做题触发词:看到“确认段通告接收窗口”→ 立即写 min(cwnd, rwnd);看到“超时”→ cwnd 归 1;看到“3 个重复 ACK”→ cwnd 减半;看到“仅正确收到第 1、3 段”→ 确认号不能跳过空洞;看到“缓存不被取走”→ rwnd 逐段递减。

来源:真题markdown/2009-2024统考真题.md 对应题号;复习资料 P5 §1.4、模板 8/10。


前后联系

  • 向前依赖:CN-0 分层与封装(段 → IP 数据报);CN-2 滑动窗口(GBN/SR 是 TCP 可靠机制的前身,X-6);CN-3 IP 的不可靠性(传输层可靠性的存在理由)、ICMP 源点抑制(路由器侧的拥塞信号,2010 年 36 题)。
  • 向后引出
    • 应用层协议全部站在 TCP/UDP 之上:DNS(UDP 53)、HTTP(TCP 80)、FTP(TCP 21/20 两条连接)、SMTP/POP3 → CN-5;
    • TCP 连接的状态(SYN_SENT、ESTABLISHED、TIME_WAIT)由 OS 的协议栈和进程共同维护 → 与 OS-1 进程 I/O 阻塞的联系;
    • 一次完整通信中 TCP 段的封装与 ARP、路由、分片的协作 → CN-6 全景(2024-47 即 FTP 场景下的 TCP+IP+应用层综合)。

闭卷回忆链

  1. IP 已经能把分组送到主机,为什么还要传输层?(进程寻址 + 可靠性 + 两种控制)
  2. 分组到了主机,怎么知道交给哪个进程?(端口;UDP 分用看目的端口)
  3. UDP 什么都不保证,为什么还存在?(低时延、无状态、首部小;DNS/实时场景)
  4. TCP 用什么三件套实现可靠?(序号 + 累计确认 + 超时重传)
  5. 乱序到达时确认号怎么定?(连续正确接收的下一字节,不跳空洞)
  6. 握手为什么三次、挥手为什么四次?(失效请求 + 双方 ISN 确认;全双工两方向分别关)
  7. SYN、FIN 在序号上有什么特殊性?(各占 1 个序号)
  8. 发送方能发多少由谁决定?(min(cwnd, rwnd))
  9. 为什么有 rwnd 还要 cwnd?(接收方装得下 ≠ 网络扛得住)
  10. 慢开始为什么敢指数增长?为什么还要 ssthresh?(快速爬坡;逼近极限要改加法)
  11. 超时和 3 个重复 ACK 分别说明什么?处理为何不同?(严重 vs 轻度;归 1 vs 减半)
  12. 给定超时点和 ssthresh,怎么数 RTT 恢复窗口?(慢开始翻倍到门限,再每 RTT +1)
  13. TCP 的滑动窗口和链路层 GBN/SR 是什么关系?(同思想两层实例;帧 vs 字节,单链路 vs 端到端)