TCP 解决流水线的差错恢复 GBN协议
回退N步 GBN
允许发送方发送多个分组而不需等待确认,但是它也受限于流水线中未确认的分组数不能超过某个最大允许数N。
基序号(base): 定义为最早未确认的分组的序号
下一个序号(nextseqnum): 定义为最小的未使用序号 (其实就是下一个要发送的序号)
为什么要设置为N? 流量控制是对发送方施加限制的原因之一。
TCP有一个32bit的序号字段,其中的TCP序号是按字节流中的字节进行计数的,不是按照分组计数的。
发送方
GBN的发送方需要满足三种类型的事件:
- 上层调用:
上层调用rdt_send()
实际中发现发送方更可能去缓存这些数据, 或者采用同步机制,仅当窗口不满时才调用rdt_send()if 已发送的未确认的序号段长度 < N: 产生一个分组,并且发送 然后让nextseqnum ++; else: 告诉上层窗口满了。
- 收到一个ACK
在GBN协议中,对序号为n的分组的确认采取 累积确认的方式,表明接收方已正确接收到序号为n的以前且包括n在内的所有分组。 - 超时事件
协议的名字GBN来源于出现 丢失和时延过长分组时,发送方的行为。
定时器用于恢复数据或确认分组的丢失。
如果出现超时,发送方重新发送所有已发送但还未确认的分组。
仅使用一个定时器,可以被当作是最早的已发送但未被确认的分组所使用的定时器。
收到一个ACK,但仍有已发送但未被确认的分组,则定时器被重新启动。
如果没有已发送但未被确认的分组,才停止这个定时器。
接收方
if 分组按序且安全到达:
发送一个ACK
将分组中的数据交给上层
else:
丢弃该分组
重新发送一个ACK,为最近按序接收的分组发送
这样出现了一个结论,如果分组k已经接受并交付,则所有序号小于k的分组都已经交付。
因此,使用累计确认是GBN一个自然的选择。
优缺点:
优点: 发送缓存和接受缓存都很简单,接收方不需要缓存任何失序的分组。
发送方无非维护窗口的上下边界,base和nextseqnum就好了。
接收方只需要维护唯一信息:下一个按序接受的分组的序号。
缺点:丢弃一个正确接收的分组,随后对该分组的重传也许会丢失或者出错,也许会出现更多的重传
单个分组的差错就能够引起GBN重传大量分组,许多分组根本没有必要重传
到最后做一个总结吧:
- GBN协议: 允许发送方连续发送多个分组而不需要等待,发送的个数会受到发送窗口N大小的限制。
- GBN协议发送方要接受3个系统调用:
- send:能发就发,不能发就等
- 收到ack:能移动base就移base,同时重启计时器
- 超时:把[base:nextseqnum - 1]全部重新发! 重启计时器
- GBN协议接收方
接受的按序,就把分组留下交给上层。
不按序就扔了。
然后发送一个ACK给发送方 - GBN名称和发送方很相关,累计确认却是接收方做的事!
分类:
网络
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?