序号与确认
复习
- 三次握手:双方同步各自的初始序号与收发能力
- TCP 为什么需要连接:可靠传输需要双方维护状态
- UDP:不保证送达与顺序
TL;DR
- TCP 给每个字节编号,接收方按序号判断丢失、重复与乱序
- 接收方用确认告诉发送方“我已经收到了哪里”
- 累积确认:确认到某个序号,表示它之前的都收到了
- 序号与确认,是重传和顺序控制的基础
正文
连接建立后,双方约定好了初始序号。现在可以正式传数据了。可数据在不可靠的网络里会丢失、重复、乱序,接收方怎么知道“我拿到的是不是完整的、正确的”?
答案是把字节都编上号,再让接收方逐段确认。
给每个字节编号
TCP 把数据看作一条字节流,并为每个字节编上序号。发送方发出一段数据时,会带上“这一段从第几个字节开始”。
接收方拿到后,就能据此判断:
- 序号正好是期望的:收下,继续往后
- 序号重复了:说明是之前那段的副本,直接丢弃
- 序号跳过了:说明中间丢了,先记下缺口
有了序号,接收方就不再是“闷头收”,而是能清楚地知道“我收到哪了、还缺哪段”。
确认:告诉对方我的进度
光自己知道还不够,发送方也得知道。于是接收方会回确认(ACK),告诉发送方自己收到了哪里。
TCP 用的是累积确认:确认里填的,通常是“我下一个期望的序号”。这句话的含义是——这个序号之前的字节,我都已经收到了。
比如接收方回“下一个期望是 1001”,就等于说“0 到 1000 这段我都拿到了”。发送方一看便知:这部分可以放心,不用再重发了。
为什么确认“下一个期望的”
你可能会想:为什么不直接说“我最后收到的是 1000”?
因为“下一个期望的序号”更精确,也更不易混淆。它明确划出一条分界线:分界线左侧,全都收妥了;分界线右侧,还没到。 如果只说“最后收到 1000”,一旦有乱序、有缺口,就容易含糊。用“下一个期望”,发送方一眼就能看出“该从哪里接着发、哪里需要补”。
思考题 1
为什么确认“下一个期望的序号”,比确认“最后收到的序号”更清晰?
思考题 2
接收方收到一个重复的段,为什么可以直接丢弃?
小结
知识点
- TCP 为字节流编号,用于判断丢失、重复与乱序
- 接收方用确认告知收到进度
- 累积确认表示“该序号之前都已收到”
- 序号与确认是可靠传输的基础
参考资料
- Wikipedia(zh):传输控制协议:序号、确认与可靠传输
- Wikipedia(zh):GO-BACK-N:基于确认与重传的传输机制
思考题答案(仅供参考)
思考题 1
“下一个期望的序号”直接划出了一条清晰的界线:它之前的都收妥了,它之后的还没到。这样发送方一眼就能知道从哪儿接着发、哪里需要补。而“最后收到的序号”在有乱序和缺口时含义模糊,容易让人误解进度。
思考题 2
因为它携带的字节序号小于接收方当前的期望值,说明这段数据之前已经收到并确认过了。重复处理毫无意义,丢弃即可,同时通常还会再回一个确认,提醒对方进度。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪