回退N帧协议(GBN)有差错情况下的详细流程
回退N帧协议(GBN)有差错情况下的详细流程
场景设置
- 发送窗口大小: 5(允许同时发送5个未确认的分组)
- 接收窗口大小: 1(只接收按序到达的下一个分组)
- 序号范围: 0-7(8个可用序号,循环使用)
- 差错假设: 数据分组4在传输过程中出现误码
详细流程图示
步骤0: 初始状态
发送方 接收方
[0][1][2][3][4][ ][ ][ ] [0][ ][ ][ ][ ][ ][ ][ ]
↑ ↑
发送窗口起点 接收窗口起点
解释: 通信开始时,发送方的发送窗口包含序号0-4的分组,窗口起点在序号0。接收方的接收窗口只有序号0,表示接收方期望接收的下一个分组是序号为0的分组。
步骤1: 发送方发送序号0-4的五个分组
[0][1][2][3][4][ ][ ][ ] [0][ ][ ][ ][ ][ ][ ][ ]
↑ ↑
└─分组0──────────────────────────────→└─(接收)
└─分组1───────────────────────────→ └─(等待)
└─分组2─────────────────────────→ └─(等待)
└─分组3───────────────────────→ └─(等待)
└─分组4─────────────────────→ └─(等待)
解释: 发送方利用流水线传输的优势,不等待确认就连续发送了5个分组(序号0-4)。发送方为每个发出的分组启动计时器。这5个分组开始在网络中传输。
步骤2: 接收方正确接收分组0,发送ACK0
[0][1][2][3][4][ ][ ][ ] [ ][1][ ][ ][ ][ ][ ][ ]
↑ ↑
分组0已接收并交付上层
接收窗口向右滑动一位
┌───────────────────────┘
│
↓
ACK0返回中
解释: 分组0正确到达接收方。接收方检查无误后接收该分组,将数据交付给上层,并将接收窗口向右滑动一位(从序号0移动到序号1)。接收方发送确认分组ACK0,表示已正确接收序号为0的分组。
步骤3: 发送方收到ACK0,窗口滑动,发送序号5的新分组
[ ][1][2][3][4][5][ ][ ] [ ][1][ ][ ][ ][ ][ ][ ]
↑ ↑
发送窗口向右滑动一位 接收窗口起点
序号5进入窗口
└分组0从缓存移除
└─分组5─────────────────────────────→ └─(等待)
解释: 发送方收到ACK0,确认序号0的分组已被正确接收。发送窗口向右滑动一位,序号5进入窗口,发送方立即发送序号为5的分组。同时,序号0的分组可以从缓存中删除(因为已被确认)。
步骤4: 类似步骤2-3,接收方正确接收分组1-3,发送ACK1-3
[ ][ ][ ][3][4][5][6][7] [ ][ ][ ][4][ ][ ][ ][ ]
↑ ↑
发送窗口起点移动到序号3 接收窗口起点移动到序号4
(已收到ACK1,ACK2,ACK3) (已接收并处理分组1,2,3)
└─分组6─────────────────────→ └─(等待)
└─分组7───────────────────→ └─(等待)
解释: 这一步压缩了多个类似交互。分组1、2、3正确到达接收方,接收方依次发送ACK1、ACK2、ACK3。发送方收到这些确认后,发送窗口连续向右滑动,新的序号(6、7)进入窗口并被发送出去。此时发送窗口包含序号3-7,接收窗口位于序号4。
步骤5: 分组4传输出错(误码),接收方丢弃
[ ][ ][ ][3][4][5][6][7] [ ][ ][ ][4][ ][ ][ ][ ]
↑ ↑
△ 接收方检测到分组4有误码
│ 丢弃分组4,不移动接收窗口
│
│ ┌───────────────────────┘
↓ │
误码分组4 ↓
发送ACK3(重复确认)
解释: 关键的差错情况发生了!分组4在传输过程中出现误码。接收方通过校验机制检测到这个错误,丢弃分组4,接收窗口保持不变(仍在序号4)。接收方发送ACK3,表示已正确接收到序号3及之前的分组,期望接收序号4的分组。
步骤6: 发送方收到ACK3,但分组5、6、7到达接收方
[ ][ ][ ][3][4][5][6][7] [ ][ ][ ][4][ ][ ][ ][ ]
↑ ↑
└分组5已到达接收方──────────────→└(接收窗口期望序号4)
检测到分组5与窗口不符,丢弃
发送ACK3(又一个重复确认)
└分组6已到达接收方──────────────→└(接收窗口仍期望序号4)
检测到分组6与窗口不符,丢弃
发送ACK3(又一个重复确认)
└分组7已到达接收方──────────────→└(接收窗口仍期望序号4)
检测到分组7与窗口不符,丢弃
发送ACK3(又一个重复确认)
解释: 分组5、6、7陆续到达接收方。但由于接收窗口仍在序号4(期望接收序号4的分组),这些分组与接收窗口不匹配,都被接收方丢弃。对于每个被丢弃的分组,接收方都发送ACK3(表示最后一个正确接收的分组序号)。这导致发送方收到多个重复的ACK3。
步骤7-A: (情况一)分组4的计时器超时触发重传
[ ][ ][ ][3][4][5][6][7] [ ][ ][ ][4][ ][ ][ ][ ]
↑ ↑
└分组4计时器超时
└重传分组4───────────────────────→└(接收)
└重传分组5─────────────────────→└(等待)
└重传分组6───────────────────→└(等待)
└重传分组7─────────────────→└(等待)
解释: 在某些实现中,如果分组4的计时器超时(即在预定时间内未收到确认),发送方会重传当前窗口内所有未确认的分组,即序号4-7的分组。这些重传的分组开始传输到接收方。
步骤7-B: (情况二)收到多个重复ACK3触发重传
[ ][ ][ ][3][4][5][6][7] [ ][ ][ ][4][ ][ ][ ][ ]
↑ ↑
└收到3个重复ACK3,触发快速重传
└重传分组4───────────────────────→└(接收)
└重传分组5─────────────────────→└(等待)
└重传分组6───────────────────→└(等待)
└重传分组7─────────────────→└(等待)
解释: 在其他实现中,发送方收到多个重复的ACK3(通常是3个,这种机制类似于TCP的快速重传),会立即重传分组,而不等待计时器超时。这样可以更快地恢复通信,减少延迟。无论使用哪种触发机制,重传的行为是相同的。
步骤8: 重传的分组4正确接收,接收窗口滑动
[ ][ ][ ][3][4][5][6][7] [ ][ ][ ][ ][5][ ][ ][ ]
↑ ↑
重传的分组4正确接收
接收窗口滑动到序号5
┌───────────────────────┘
│
↓
发送ACK4
解释: 重传的分组4正确到达接收方。接收方检查无误后接收该分组,将数据交付给上层,并将接收窗口向右滑动一位(从序号4移动到序号5)。接收方发送确认分组ACK4,表示已正确接收序号为4的分组。
步骤9: 发送方收到ACK4,窗口滑动,发送新分组
[ ][ ][ ][ ][4][5][6][7] [ ][ ][ ][ ][5][ ][ ][ ]
↑ ↑
发送窗口向右滑动一位 接收窗口起点
序号0进入窗口
└─分组0───────────────────────────→└(等待)
解释: 发送方收到ACK4,确认序号4的分组已被正确接收。发送窗口向右滑动一位,序号0进入窗口(序号是循环使用的),发送方立即发送序号为0的分组。同时,序号4的分组可以从缓存中删除(因为已被确认)。
步骤10: 重传的分组5正确接收,通信逐步恢复
[ ][ ][ ][ ][4][5][6][7] [ ][ ][ ][ ][ ][6][ ][ ]
↑ ↑
重传的分组5正确接收
接收窗口滑动到序号6
┌───────────────────────┘
│
↓
发送ACK5
解释: 重传的分组5正确到达接收方。接收方检查无误后接收该分组,将数据交付给上层,并将接收窗口向右滑动一位(从序号5移动到序号6)。接收方发送确认分组ACK5,表示已正确接收序号为5的分组。
步骤11: 类似步骤10,分组6和7被正确接收,窗口继续滑动
[ ][ ][ ][ ][ ][ ][ ][7] [ ][ ][ ][ ][ ][ ][ ][0]
↑ ↑
发送窗口起点在序号7 接收窗口起点在序号0
(收到ACK5,ACK6) (已接收并处理分组6,7)
解释: 重传的分组6和7也正确到达接收方,接收方发送ACK6和ACK7。发送窗口继续向右滑动。现在发送窗口起点在序号7,接收窗口起点在序号0。
步骤12: 通信完全恢复正常
[0][1][2][3][ ][ ][ ][7] [0][ ][ ][ ][ ][ ][ ][ ]
↑ ↑
发送窗口起点移到序号0 接收窗口起点在序号0
(收到ACK7) (已接收并处理分组7)
解释: 发送方收到ACK7,发送窗口滑动到序号0。现在通信已完全恢复正常状态,发送方和接收方可以继续新一轮的数据传输。
回退N帧协议的关键特点总结
-
选择性丢弃:
- 接收方只接受按序到达的分组
- 任何不符合期望序号的分组都会被丢弃,即使它们是正确的
-
累计确认:
- 确认号n表示序号n及之前的所有分组已正确接收
- 这减少了确认分组的数量,但在出错时会导致更多的重传
-
重传触发机制:
- 超时重传: 分组的计时器超时
- 重复ACK触发: 连续收到多个相同的确认号
-
全窗口重传:
- 一旦检测到错误,发送方重传从出错分组到窗口末尾的所有分组
- 这就是"回退N帧"的由来 - 需要回退到出错的地方,重新发送多个分组
-
效率考量:
- 在低错误率的信道上,GBN协议效率高
- 在高错误率的信道上,大量重传会导致效率下降