3.4 可靠数据传输原理
可靠数据传输是计算机网络通信的核心基石,它解决了分组丢失、比特差错、乱序到达等不可靠信道问题,确保发送方的数据能完整、按序、无丢失地交付给接收方。我们将从最基础的协议模型出发,逐步迭代到工业级的流水线协议,拆解每一步的设计逻辑与实现细节。
3.4.1 构造可靠数据传输协议
我们从理想信道开始,逐步叠加现实中的信道问题,构建出完整的可靠传输协议栈(RDT 系列)。
1. 理想信道:RDT 1.0(完全可靠)
假设前提:
- 底层信道无任何差错:比特不会翻转、分组不会丢失、不会乱序。
- 发送方与接收方处理速度匹配,不会出现拥塞。
核心逻辑:
- 发送方:从上层获取数据→封装成分组→交付给网络层。
- 接收方:从网络层接收分组→提取数据→交付给上层。
- 无额外控制机制,仅需基础的发送 / 接收接口。
状态机描述:
发送方状态:等待上层数据 → 发送分组 → 回到等待状态
接收方状态:等待网络层分组 → 提取数据交付 → 回到等待状态
局限:仅存在于理论模型,无法应对真实网络的任何差错。
2. 存在比特差错:RDT 2.0(停等 + 差错检测)
问题引入:真实信道中,电磁干扰、噪声会导致比特翻转(如0→1),接收方可能收到错误数据。
核心机制:
- 差错检测:发送方在分组头部加入校验和(Checksum),接收方收到后重新计算校验和,与头部值对比:
- 一致:分组无差错,回复
ACK(确认)。 - 不一致:分组出错,回复
NAK(否定确认)。
- 一致:分组无差错,回复
- 确认与重传:
- 发送方发送分组后,等待接收方的
ACK/NAK。 - 收到
ACK:发送下一个分组。 - 收到
NAK:重传当前分组,直到收到ACK。
- 发送方发送分组后,等待接收方的
状态机演进:
发送方:等待上层数据 → 发送分组 → 等待ACK/NAK
↙(收到ACK) ↖(收到NAK/重传)
回到等待数据 重传当前分组
接收方:等待分组 → 校验差错 → 回复ACK/NAK → 回到等待状态
关键缺陷:未考虑ACK/NAK本身出错或丢失的情况,会导致发送方无限等待。
3. 确认分组出错 / 丢失:RDT 2.1(引入序号)
问题引入:ACK/NAK作为控制分组,也可能在信道中比特翻转或丢失,发送方无法判断 “分组是否被接收”。
核心改进:
- 分组序号:为每个数据分组分配交替序号(0 或 1),解决重复分组的歧义。
- 重复处理:
- 接收方收到重复序号的分组(如连续两个
seq=0),直接丢弃并重传对应的ACK。 - 发送方收到重复
ACK(如两次ACK=0),忽略即可,说明分组已被接收。
- 接收方收到重复序号的分组(如连续两个
典型场景:
- 发送方发送
seq=0分组,接收方收到后回复ACK=0,但ACK=0丢失。 - 发送方超时未收到确认,重传
seq=0分组。 - 接收方收到重复
seq=0,丢弃并重新发送ACK=0。 - 发送方收到
ACK=0,确认分组已送达,开始发送seq=1。
优势:彻底解决了 “确认分组丢失 / 出错” 导致的状态歧义。
4. 分组完全丢失:RDT 3.0(加入定时器)
问题引入:不仅控制分组会丢失,数据分组也可能在信道中完全消失(如路由器拥塞丢弃),发送方永远收不到ACK/NAK。
核心改进:
- 定时器机制:发送方每发送一个分组,就启动一个超时定时器。
- 若定时器超时前收到
ACK:关闭定时器,发送下一个分组。 - 若定时器超时未收到
ACK:重传当前分组,重启定时器。
- 若定时器超时前收到
- 停等协议(Stop-and-Wait):每次仅发送一个分组,必须等待确认后才能发送下一个,避免窗口溢出。
性能瓶颈:停等协议的信道利用率极低,公式为:U=RTT+L/RL/R
- L:分组长度(bit)
- R:链路带宽(bps)
- RTT:往返时延(s)
示例:1Gbps 链路,100ms RTT,分组大小 1KB(8192bit):U=0.1+8192/1098192/109≈0.008%即 99.992% 的时间链路都在空闲等待,效率极低。
3.4.2 流水线可靠数据传输协议
为解决停等协议的低效率,我们引入流水线技术:允许发送方连续发送多个分组,无需等待逐个确认,大幅提升信道利用率。
核心设计变更
- 发送窗口:定义
窗口大小N,表示发送方可同时发送的未确认分组数量上限。 - 序号空间扩展:从 2 位(0/1)扩展为更大的循环序号(如 32 位 TCP 序号),避免窗口内序号重复。
- 累积确认 / 独立确认:接收方可以一次性确认多个分组,减少控制报文开销。
两种经典流水线协议
- 回退 N 步(Go-Back-N, GBN):实现简单,丢包时批量重传。
- 选择重传(Selective Repeat, SR):效率更高,仅重传丢失的分组。
3.4.3 回退 N 步(GBN)
GBN 是最经典的流水线协议,核心思想是 “累积确认 + 批量重传”,实现成本低,适合早期网络。
1. 发送方核心机制
- 窗口变量:
base:最早未确认分组的序号(窗口左边界)。nextseqnum:下一个待发送分组的序号(窗口右边界 + 1)。- 窗口大小:N=nextseqnum−base,满足 nextseqnum≤base+N。
- 定时器:仅维护一个全局定时器,为最早未确认的分组计时。
- 重传规则:
- 若定时器超时,重传所有已发送但未确认的分组(从
base到nextseqnum-1)。 - 收到
ACK n:确认所有序号≤n 的分组已接收,将base更新为n+1。若base == nextseqnum(无未确认分组),关闭定时器。
- 若定时器超时,重传所有已发送但未确认的分组(从
2. 接收方核心机制
- 累积确认:仅确认按序到达的最高序号分组,若中间分组丢失,后续乱序分组会被丢弃。
- 无缓存:接收方不缓存乱序分组,直接丢弃,等待发送方重传丢失的分组。
- ACK 规则:
- 收到
seq=expected的分组:交付上层,回复ACK=expected,expected++。 - 收到
seq≠expected的分组:丢弃,重传最近一次的ACK(即ACK=expected-1)。
- 收到
3. 优缺点分析
| 优点 | 缺点 |
|---|---|
| 实现简单,接收方无需缓存,逻辑清晰 | 单个分组丢失会导致整个窗口重传,浪费带宽 |
| 控制开销小,仅需一个定时器 | 乱序分组被丢弃,降低了信道利用率 |
| 适合丢包率低的场景 | 窗口越大,丢包后的重传代价越高 |
典型场景:发送方窗口大小 N=4,发送分组0,1,2,3,分组1丢失。接收方收到0后回复ACK=0,收到2,3时因乱序直接丢弃,并重传ACK=0。发送方超时后,重传1,2,3,直到接收方按序接收。
3.4.4 选择重传(SR)
SR 协议是 GBN 的优化版,核心思想是 “独立确认 + 选择性重传”,仅重传真正丢失的分组,最大化信道利用率。
1. 发送方核心机制
- 窗口变量:
base:窗口左边界(最早未确认分组序号)。nextseqnum:窗口右边界 + 1(下一个待发送分组序号)。- 窗口大小:N=nextseqnum−base,且必须满足 N≤序号空间/2(避免序号循环歧义)。
- 独立定时器:为每个未确认分组维护单独的定时器,超时仅重传该分组。
- 重传规则:
- 收到
ACK n:标记分组n为已接收,若n == base,则滑动窗口(base更新为最小的未接收分组序号)。 - 若分组
n的定时器超时:仅重传分组n,重启其定时器。
- 收到
2. 接收方核心机制
- 独立确认:对每个正确到达的分组(无论是否乱序),单独回复
ACK n。 - 缓存乱序分组:接收方维护一个缓存区,暂存乱序到达的分组,等待缺失分组补全后,再按序交付给上层。
- 交付规则:
- 收到
seq=base的分组:交付上层,base++,并检查缓存中是否有连续的后续分组,若有则一并交付。 - 收到
seq≠base的分组:存入缓存,回复ACK seq。
- 收到
3. 关键约束:窗口大小限制
为避免序号循环导致的歧义(如旧分组与新分组序号重叠),SR 协议要求:发送窗口大小+接收窗口大小≤序号空间通常设发送窗口 = 接收窗口 = N,因此:2N≤序号空间⟹N≤序号空间/2示例:序号空间为 8(0-7),则窗口最大为 4。若窗口为 5,发送方发送分组0-4,接收方确认后窗口滑动到5-7,0,此时旧分组0与新分组0序号重叠,无法区分。
4. 优缺点分析
表格
| 优点 | 缺点 |
|---|---|
| 仅重传丢失分组,带宽利用率最高 | 实现复杂,需为每个分组维护定时器和缓存 |
| 乱序分组被缓存,避免不必要重传 | 控制开销大,每个分组都需要独立 ACK |
| 适合高延迟、高丢包率的网络(如卫星链路) | 序号空间限制窗口大小,大带宽场景下需扩展序号位 |
典型场景:发送方窗口大小 N=4,发送分组0,1,2,3,分组1丢失。接收方收到0,2,3后,分别回复ACK=0, ACK=2, ACK=3,并缓存2,3。发送方收到ACK=0后滑动窗口,收到ACK=2,3后标记分组2,3为已接收。分组1超时后,仅重传1,接收方收到后交付1,2,3。
协议对比与工程实践
1. 三种核心协议横向对比
| 协议类型 | 窗口机制 | 确认方式 | 重传策略 | 信道利用率 | 实现复杂度 |
|---|---|---|---|---|---|
| 停等协议(RDT 3.0) | 窗口 = 1 | 逐个确认 | 重传当前分组 | 极低 | 简单 |
| 回退 N 步(GBN) | 窗口 = N | 累积确认 | 重传整个窗口 | 中等 | 较简单 |
| 选择重传(SR) | 窗口 = N | 独立确认 | 仅重传丢失分组 | 最高 | 复杂 |
2. 实际工程应用
- 数据链路层:早期的 HDLC、PPP 协议多采用 GBN,实现简单且能满足低速链路需求。
- 传输层(TCP):
- 早期 TCP 采用类似 GBN 的累积确认机制。
- 现代 TCP 引入选择性确认(SACK),融合了 SR 的核心思想:接收方通过 SACK 选项告知发送方已缓存的乱序分组,发送方仅重传丢失的分段,大幅提升了高带宽长延迟网络(如数据中心、跨洋链路)的性能。
常见问题与排查
1. 序号循环歧义
- 问题:序号空间耗尽后,新分组与旧分组序号重叠,接收方无法区分。
- 解决:严格限制窗口大小≤序号空间 / 2(SR)或窗口大小 < 序号空间(GBN),避免序号复用导致的状态混淆。
2. 定时器设置优化
- 原则:超时时间应略大于平均 RTT,通常取 Timeout=2×RTT(经验值)。
- 动态调整:实际协议(如 TCP)会根据 RTT 波动动态调整超时时间,避免过短导致的冗余重传,或过长导致的响应延迟。
3. 乱序分组处理
- GBN:直接丢弃乱序分组,依赖发送方重传,实现简单但效率低。
- SR/TCP:缓存乱序分组,等待缺失分组补全后交付,提升了信道利用率,但增加了接收方的缓存开销和逻辑复杂度。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)