引言
在这篇文章中,我们主要探讨计算机网络中的流控制协议——回退N步(GBN)协议。我们将了解它的工作原理,并探讨它如何帮助我们实现可靠的数据传输。
简介
Go-Back-N (GBN) 协议,也被称为滑动窗口协议,是一种自动重传请求(ARQ)协议。在GBN协议中,发送方可以连续发送多个数据包,而无需等待每个数据包的确认。然而,未确认的数据包数量是有限制的,不能超过预设的最大值N,这就是所谓的窗口长度。
工作原理——发送方
在GBN协议中发送方的工作流程如下
- 初始化发送窗口,发送方首先会初始化一个长度为N的发送窗口。
- 发送数据包,发送方会连续发送窗口内的数据包,为窗口中的第一个分组设置一个定时器。
- 等待确认,发送方发送数据包后,会等待接收方的确认。如果在定时器到期之前收到了接收方的确认,这时窗口中如果还有已发送但未确认的数据包,会重启定时器。如果这时窗口中已经发送的数据包都已经被确认,会停止定时器。
- 处理未确认的数据包,如果在定时器到期之前没有收到接收方的确认,发送方会重传当前窗口中所有已发送但未被确认的数据包,并重新启动定时器。
在GBN协议中,我们定义"基序号"(base)为最早发送但未被确认的数据包的序号,定义"下一个序号"(nextseqnum)为最小的未使用序号,即下一个等待发送的数据包的序号。这样,序号范围就被分隔为了四段:
- [0,base-1]:已经发送且被确认的数据包的序号
- [base,nextseqnum-1]:已经发送但未被确认的数据包的序号
- [nextseqnum,base + N - 1]:可以用于即将发送的数据包的序号
- [base + N,...):在窗口向右移动之前不能使用的序号
在实践中,如果序号字段的比特数为k,则序号范围为[0,2^k-1]。在有限的序号范围内,所有涉及序号的运算必须使用模2^k运算。
发送方FSM(有限状态机)
如上图所示,GBN发送方响应三种类型的事件
- 上层的调用,上层调用rdt_send()时,发送方首先检查发送窗口是否已满(是否有N个已发送但未被确认的分组)。如果窗口未满,将产生一个分组将其发送,并更新相应变量。如果窗口已满,会告诉上层或者缓存这些数据。
- 收到一个ACK,在GBN协议中,对序号为n的分组的确认采取累计确认的方式。表明接收方已正确接收到序号为n以前包括n在内的所有分组。
- 超时事件,发送方等待接收方的回复时,如果出现了分组丢失或时延过长定时器就会超时,发送方会重传当前窗口中所有已经发送但是未被确认的分组
工作原理——接收方
接收方一次只接收一个数据包并且在收到数据包之后检查数据包的序列号:
- 如果数据包的序列号是期望的序列号,接收方会为此分组(数据包)发送一个ACK,并将该分组中的数据交付给上层。
- 如果数据包的序列号不是期望的序列号(前面的分组出现了丢失),那么会丢弃该分组,并重发上一次的ACK。
接收方FSM(有限状态机)
接收方响应的事件可以分为两类:
- 接收到了期望的分组(接收到的分组的序号等于expectedseqnum)
处理分组:将该分组交给上层协议。
更新期望序号:更新期望的下一个序号(expected_seq_num
加 1)。
发送ACK:发送一个ACK,确认收到这个分组。ACK的序号等于接收到的分组的序号。
- 接收到非期望的分组
丢弃分组:丢弃这个分组。
发送ACK:为最近一个按序接收的分组重新发送ACK。