数据链路层的各项功能,比如差错控制、流量控制,最终都是通过协议来实现。
差错控制方法,包括了ARQ法和FEC法。
流量控制方法,包括了:停止等待方案、滑动窗口机制。
有时,一个协议会实现多个功能,比如同时实现了差错控制方法和流量控制方法。
自动重发请发法(ARQ),又分为:
- 空闲重发请求,Idle RQ
- 连续重发请求,Continuous RQ
4.3.1 停等协议(Stop and Wait)
停等协议:
结合了,流量控制方案中的停止等待方法,与差错控制方法中的空闲自动重发请求 Idle RQ。
- 发方把“待发送帧”放入缓冲区中
- 给“待发送帧”赋予帧序号,启动计时器,发送
- 收方收到帧后,放入收方缓冲区,之后进行检查。如果无差错则向发方发送一个相同帧序号的ACK确认帧
- 收方如果发现差错,则舍弃该帧
- 如果发方在规定时间内收到ACK确认帧,重置计时器,开始下一帧的发送
- 如果发方未在规定时间内收到ACK确认帧(即计时器超时),则重发发方缓冲区中的待确认帧。
特点:
- 发收双方只需要设置一个帧的缓存空间
- 待确认帧的序号只需要一个二进制位,0/1
4.3.2 顺序接收管道协议(GBN)
顺序接收管道协议:
实现了,差错控制方法中的“连续重发请求(Continuous RQ)”,和,流量控制方法中的“滑动窗口机制”。
采用GBN策略(GoBackN,回退N)的连续重发请求
GoBackN策略可以有两种实现方法:
- (发方被动检测)发方发出多帧,如果重发表的第N帧及后续帧,计时器超时后ACK确认帧仍未返回,就重新发送第N帧及后续帧
- (收方主动请求)收方检测到失错(丢失、错误)的信息帧后,请求发方重发“最后正确接收的信息帧之后的”的待确认帧
GoBackN策略的工作流程如下:
- 发方设置一个“发方缓冲区”(即重发表),采用先进先出(FIFO)的队列规则。
- 在发方,“信息帧”依次发出,其副本被放入重发表中,成为“待确认帧”。重发表是一个连续序号的队列(比如用3位二进制数表示0~7),副本帧进入重发表时被自动赋予序号。
- 到达收方的信息帧进入“收方缓冲区”,等待检错、处理。
- 收方对信息帧进行检错。如果无差错,向发方返回ACK确认帧,其中包含了信息帧的序号。同时,收方还有一个“接收次序表”,记录了最后正确接收的信息帧的序号。
- 如果发现信息帧的差错,则丢弃“该帧及所有序号大于它的后续信息帧”,从而确保了:顺序接收。
- 发方收到ACK确认帧后,删除重发表中对应序号的待确认帧。(因为收方保证了顺序接受,因此发方也会顺序删除)
- 如果发方发现重发表中某一帧的确认帧超时,说明信息帧丢失或出错。就需要退回重发表队列的头部(已确认的元素已经删除了,剩下都是未确认的),再次发送整个重发表。
疑问:
- 如果采用数据报的分组交换方式,帧可能会乱序到达收方。比如,假设第21帧没有差错,收方返回确认帧,之后又收到第16帧,发现有差错,这样就至少需要丢弃序号>=16的所有信息帧。
这样一来,收方就需要对发方本轮次发出的所有信息帧检错后,才能确定哪些帧该丢弃,哪些帧该保留。
回答:可能不影响,即使乱序,收方不断的丢弃即可。
- 收方可能还需要一个计时器来区分到达的信息帧是本轮发出的,还是下一轮次重发的。或者不同同一信息帧,在不同的重发轮次中需要编不同的序号?
否则可能带来问题:
假设发方发出第一轮次的信息帧队列,收方在处理第一轮的第12帧时发现错误,需要舍弃 序号>=12的所有信息帧。
发方无法收到 序号>=12的ACK确认帧,重新发送重发表。
收方收到重发的序号>=12的信息帧后,认为需要舍弃,于是将重发的12+信息帧也丢弃了。 发方再次重发,陷入死循环。
回答:不会发生这种事,收方丢弃以后,应该会等待接收新的第12+帧
采用滑动窗口机制(slidding window),进行流量控制
回退N策略的连续重发请求,确实提高了信道的利用率,但也存在一些缺点:
- 已发送待确认的帧越多,当其中某帧失错后,需要重发的帧也就越多
- 发方缓存可能会过载:如果发方发出速度高于收方的接收处理速度,发方重发表种的帧数量就会不断增长,直到超出缓存区大小。
因此,必须控制发方“待确认帧”的数量,也就是流量控制,这可以通过窗口机制来实现。
窗口机制:
- 发方设置了“发送窗口”:容纳“已发送、待确认的帧”。发送窗口是重发表的子集,其元素个数称为窗口尺寸。
- 收方设置了“接收窗口”:容纳“等待接收的帧”
状态变化过程如下:
- 发方没有发出信息帧,发方窗口上下沿重合,没有元素。收方窗口打开帧0,等待接收。
- 发方窗口容纳帧0,帧0发出待确认,收方窗口等待帧0。(此时信息帧0还未到达收方)
- 因为发方窗口最大尺寸为2,在帧0未收到确认帧前,还可以发出帧1,因此发方窗口容纳了帧0帧1。收方窗口仍然等待帧0。
- 发方窗口容纳帧0帧1,等待确认帧;收方窗口接收了信息帧0,返回了帧0的确认帧,然后关闭帧0窗口,打开帧1窗口,等待接收帧1。
- 发方收到帧0的确认帧,关闭帧0的窗口,此时发送窗口容纳了帧1;收方继续等待帧1的信息帧。
- 发方打开帧2的窗口,此时发方窗口容纳了帧1帧2;收方窗口收到帧1,返回了帧1的确认帧,之后关闭帧1窗口,打开帧2窗口,等待接收帧2.
- 发方收到帧1的确认帧,关闭帧1窗口,此时发送窗口容纳了帧2;收方继续等待帧2的信息帧。
需要说明:
因为信息帧和确认帧在每次传输中花费的时间都可能不相同,因此,上图中各状态不会随时间规律变化,从某个状态到另一个状态可能花费很长时间,也可能很短时间。
引申:
- 停等协议:发送窗口尺寸=1,接收窗口尺寸=1
- GoBackN协议:发送窗口尺寸>1,接收窗口尺寸=1
4.3.3 选择重传协议(SR,Selective Repeat)
GoBackN协议的缺点:
收方收到多帧,即使只有中间第n帧出错,后续帧都无差错,也需要发方重发第n帧及后续帧。这是一种浪费。
此时可以采用选择重传策略:
- 收方收到多帧,如果中间有少量帧出现错误,其后续帧没有错误,那么就把后续的正确帧先放入缓存,向发方返回错误帧的“否认帧”NAK。
- 发方收到“否认帧”NAK后,不需要等待该帧的计时器超时,就可以重发出错的帧。
- 收方收到重发的帧后,将其与先前缓存的帧组装后,递交给网络层。
显然,选择重传策略具有一些优势:
- 减少浪费:只要求发方重发错误帧。
- 节约了等待超时的时间:GBN策略中,发方需要等待失错帧超时。(收到否认帧即可重发)
唯一的缺点是:收方需要较大的缓存空间。
图上信息帧2到达收方后出错,收方返回NAK否认帧,而后续的帧3,4,5都没有错误,被放入缓存中,同时收方返回ACK确认帧。发方收到NAK否认帧后,再次重发帧2。
SR策略中,一定范围内不按顺序到达的帧都可以接收,如果将这个范围视为窗口,那么SR策略中接收窗口是大于1的。
注意:选择重传协议也会丢弃分组,它只能暂存窗口范围内的分组,超过窗口的分组仍然只能丢弃。
发送窗口和接收窗口的尺寸问题
假设重发表中的帧序号采用3位2进制数表示,则最大帧序号 \(S_{max}=2^3-1=7\)
有序接收方式
对于有序接收方式(比如Stop and Wait、GBN),发送窗口的最大尺寸可以等同于重发表的最大序号。\(S_{max} = 2^m -1\)。m是重发表的最大序号,从10进制形式转换成2进制形式后的位数。
比如重发表序号为0~7,则 m = 3。
接收窗口大小始终为1。
发送窗口尺寸不能大于重发表序号范围。
例如重发表最大序号是3,允许的序号:0,1,2,3;发送窗口尺寸是6。
窗口中帧的序号就会被标记为 0,1,2,3,0,1。
当收到接收方返回的ACK确认帧时,就无法分辨到底时第一个0帧,还是第二个0帧。
接收方一般都是采用“累积确认”的方式。接收方不必对收到的帧逐个发送确认,可以在收到几个帧后,对按序到达的最后一个帧发送确认,这样就表示:到 这个帧为止的所有帧都已正确收到了。
对于无序接收方式
对于无序接收方式(SR策略),发送窗口的最大尺寸,最多只能是\(S_{max} \cdot 1/2\)。
首先,无序接收方式中,
- 发送窗口不能比接收窗口大,不然接收窗口可能会溢出。但接收窗口可以比发送窗口大。因此,发送窗口 <= 接收窗口
增大发送窗口可以提高传输效率,但要避免产生二义性。
假设重发表序号最大为7(即序号为0,1,2,3,4,5,6,7),设发送窗口和接收窗口的尺寸都为5(0,1,2,3,4)。
同时假设:发送窗口发出0,1,2,3,4帧,接收窗口全部接收成功,返回ACK,接收窗口向前移动,等待接收5,6,7,0,1帧(注意:这里帧的序号溢出了队列,导致循环)。
再假设,发送窗口并没接收到任何确认帧(返回的ACK全部丢失)。
此时,只能重发0,1,2,3,4帧。而接收窗口就无法区分0,1帧到底是重发的,还是本轮应该等待的,这就是二义性。因为发送窗口<=接收窗口。要最大化传输效率,应使 发送窗口尺寸=接收窗口尺寸。
假设发送窗口尺寸为M,接收窗口尺寸也为M。发送窗口发出M个帧后,接收窗口向前移动M格,接收窗口等待序号为 M+1,M+2,...2M的帧。要避免二义性,就必须满足2M<=重发表序号最大值。
用窗口的观点来看三种策略
可以用窗口的观点来看待三种策略:
- 停等 : 发送窗口 =1 ,接收窗口 =1
- GBN : 发送窗口 >1 ,接收窗口 =1
- SR选择重传:发送窗口 >1 ,接收窗口 >1