CS 168 · LECTURE 11 · 2026-10-01 · 传输

可靠传输:序号、确认与重传

IP 可以丢、乱、重,TCP 却向应用提供有序字节流;这层幻觉由序号、累计确认、定时器与重传共同维护。

版本快照:Fall 2026 官方课表与在线教材,核对日期 2026-09-02;官网仍标注 under construction,日期与政策可能变化。
历史证据边界:PointBreaker 仓库只用于复盘 invariant 与 bug,不代表 Fall 2026 当前提交接口。

  1. 互联网地基
  2. 路由
  3. 传输
  4. 应用与端到端
  5. 数据中心
  6. 群体通信
  7. 无线与移动

本章核心问题

接收方只返回一个 ACK 数字,发送方怎样判断哪些字节安全、哪些需要重传?

1 · 字节流而非消息

TCP 不保留应用 send() 的消息边界。一次写入可能拆成多个 segment,多次写入也可能合并;接收应用只看到按序字节。因此应用协议必须自行定义长度、分隔符或 framing。

sequence number 标识 segment payload 的第一个字节。SYN 与 FIN 虽不携带应用数据,也各占一个序号空间,使连接建立和关闭能被确认与重传。

2 · 累计 ACK 与滑动窗口

若收到 ACK 500,表示 500 之前的所有字节已连续到达。发送方把 snd.una 推到 500,释放相应重传队列项。ACK 不一定对应单个包,而是确认连续前缀。

发送窗口右边界约为 snd.una + advertised_windowsnd.nxt - snd.una 是在途字节,真正可发送量是窗口减去在途量;只比较新数据长度与总窗口会在已有未确认数据时超发。

3 · 丢失、乱序与重复

接收方只把连续字节交给应用,乱序 segment 暂存在 receive queue,并重复确认当前 rcv.nxt。缺口补上后,可连续消费多个排队片段并一次推进 ACK。

发送方用超时恢复无反馈的丢包;现代 TCP 还可用重复 ACK 触发快速重传。重传必须使用原序号,且不能把同一逻辑字节重复推进 snd.nxt

4 · RTO 与可辨识性

RTT 会变化,所以 RTO 同时估计中心与偏差;先用旧均值更新偏差:

\[\mathrm{RTTVAR}\leftarrow(1-\beta)\mathrm{RTTVAR}+\beta\lvert\mathrm{SRTT}_{\mathrm{old}}-R\rvert\]\[\mathrm{SRTT}\leftarrow(1-\alpha)\mathrm{SRTT}_{\mathrm{old}}+\alpha R\]\[\mathrm{RTO}=\mathrm{SRTT}+\max(G,4\,\mathrm{RTTVAR})\]

发生重传后,收到 ACK 时无法判断确认的是原包还是重传包,Karn 思路要求不把这次 RTT 当作干净样本。超时还应指数退避,避免拥塞时更猛烈地重发。

纠错:最容易带走的错误模型

闭卷推演

初始序号 100,依次收到 payload 范围 [200,300)、[100,150)、[150,200)。每一步写出 receive queue、rcv.nxt 与 ACK。

检查:发送窗口 1000 B,已有 700 B 未确认,当前最多还能新发多少?

开始前:三类问题不是同义词

Scenario真正稀缺/不确定的对象机制
segment 丢失发送方不知道哪些字节已连续抵达Reliability:sequence、ACK、timer、retransmission
receiver 太慢接收缓存空间Flow control:advertised receive window
network overloaded路径中的队列/链路容量Congestion control:根据网络反馈调节发送

一个 window 字段不能替代三套机制:接收方有空间不代表网络不拥塞;网络空闲不代表接收应用读得够快;两者都不能告诉发送方具体哪段字节丢了。

检查:接收端应用暂停读取、但网络空闲,首先限制发送方的应是什么?

完整 TCP state trace:缺口、乱序、超时与累计 ACK

初始发送方 SND.UNA=100SND.NXT=100SND.WND=400;接收方 RCV.NXT=100、receive window 400、乱序队列为空。

Step / eventSender afterReceiver afterwire output为何这样更新
0 · initialUNA=100, NXT=100, retx=[]NXT=100, OOO=[]没有在途字节
1 · send [100,200), lostUNA=100, NXT=200, retx=[[100,200)];启动 oldest-unacked timer不变segment 消失发送推进 NXT,但未确认不能推进 UNA
2 · send [200,300), arrivesUNA=100, NXT=300, retx 两项NXT=100, OOO=[[200,300)]ACK 100[100,200) 是洞,不能越洞交付
3 · ACK 100 arrivesUNA 仍 100;队列不弹出不变累计 ACK 没有确认新连续字节
4 · timeout oldest重发 [100,200),NXT 仍 300;RTO backoff不变retransmit seq=100重传同一逻辑字节,不能再次消耗序号
5 · retransmission arrives等待 ACK先交付 [100,200),再从 OOO 连续取 [200,300);NXT=300, OOO=[]ACK 300缺口闭合后连续前缀一次扩展两段
6 · ACK 300 arrivesUNA=300, NXT=300, retx=[];停止 timerNXT=300所有在途字节成为已确认前缀

发送空间始终满足 \(\mathrm{SND.UNA} \leq \mathrm{SND.NXT} \leq \mathrm{SND.UNA}+\mathrm{SND.WND}\)。接收端只向应用交付小于 RCV.NXT 的连续前缀。

检查:Step 2 收到 [200,300) 后,RCV.NXT 应是多少?

检查:Step 4 重传后,SND.NXT 为什么不变成 400?

RTO:估计不确定性,而不是猜固定秒数

对未重传样本 \(R\),先用旧均值更新偏差,再更新均值:\[\mathrm{RTTVAR}\leftarrow(1-\beta)\mathrm{RTTVAR}+\beta\lvert \mathrm{SRTT}_{\mathrm{old}}-R\rvert\] \[\mathrm{SRTT}\leftarrow(1-\alpha)\mathrm{SRTT}_{\mathrm{old}}+\alpha R\] \[\mathrm{RTO}=\mathrm{SRTT}+\max(G,4\,\mathrm{RTTVAR})\]

SRTT 跟踪中心,RTTVAR 为抖动留余量,G 是时钟粒度。若包被重传,随后 ACK 可能对应原发送或重传,样本归属不可辨识;Karn 的原则是跳过该 RTT 样本,并在 timeout 后退避 RTO。

Counterfactual:如果乱序段一到就交付

应用会先读到 [200,300),以后再读 [100,200),TCP 对“有序字节流”的承诺被破坏。若仍发送 ACK 300,发送方还会删除其实未到的 [100,200);可靠性状态与应用可见结果同时损坏。OOO queue 的存在不是性能优化,而是把已收到集合与可交付连续前缀分开。

误解拆解:ACK 100 是“收到了 100 号包”

为什么诱人
许多协议把 ACK 当成某个消息 ID 的回执。
具体反例
接收 [200,300) 时仍回 ACK 100;它恰恰表示从 100 开始还有洞,而不是确认名为 100 的 packet。
正确模型
TCP 给字节编号。ACK=N 是一个边界:N 以前的连续字节已收到,下一个期待 N。

历史 transport 实现:条件保护的不变量

ACK 后弹 retx queue
只删除完全落在累计确认边界之前的 segment。
OOO queue consume loop
只有队首覆盖 RCV.NXT 才交付;遇洞停止。
重传不推进 NXT
一个逻辑字节在 sequence space 中只有一个编号。
Karn guard
有重传歧义的 ACK 不污染 RTT estimator。

这些映射来自你的历史仓库,用来复盘 invariant 与 bug;不是 Fall 2026 Project 3 官方答案。当前官方 P3 仍未发布。

Timeline 深度检查

检查:ACK 300 到达时,发送方可删除哪些重传项?

检查:网络严重拥塞但 receiver window 很大,哪项仍必须独立限制发送?

检查:为什么重传后的 ACK 不宜更新 SRTT?

Explain It Yourself

  1. 盖住 trace,逐步写出 UNA/NXT/retx queue、RCV.NXT/OOO queue 和每个 wire output。
  2. 用三个不同 scenario 解释 reliability、flow control、congestion control 为什么不能互相替代。
自检标准

如果答案没有说明“连续前缀”“重传不推进 NXT”“receiver state 与 network state 不同”,继续重画 timeline。

一手资料

正文是 CourseStack 的中文解释与重新绘制的教学例子;官方页面负责课程原始定义,历史仓库只提供你的实现证据。