引言
在GBN协议中,如果窗口中有一个数据包丢失,即使窗口中其他所有的数据包都已经被接收方正确接收,发送方也需要重传窗口中的所有数据包,这会造成大量不必要的重传,降低了数据传输的效率。
为了解决这个问题,出现了其他的自动重传请求(ARQ)协议。本文探讨的内容为选择重传(Selective Repeat,SR)协议。在SR协议中,接收方可以接收和确认非顺序的数据包,而发送方只需要重传那些未被确认的数据包,从而提高了数据传输的效率。
简介
选择重传(SR)协议是一种自动重传请求(ARQ)协议,其主要目标是提高数据传输的可靠性和效率。在SR协议中,发送方和接收方各自维护一个窗口(对SR协议来说,发送方和接收方的窗口并不总是一致)。发送方只重传那些未被确认的数据包,而接收方可以接收和确认非顺序的数据包。
工作原理
发送方
- 初始化发送窗口,发送方首先会初始化一个长度为N的发送窗口,窗口中的每个位置对应一个数据包,窗口中的每一个数据包都有一个唯一的序列号。定义send_base(发送窗口的左边界,表示当前最早未被确认的序号),nextseqnum(表示下一个可用的序号)。
- 从上层收到数据,当从上层接收到数据时,SR发送方会检测当前窗口是否还有可用的序号,如果当前窗口有可利用的序号,将数据打包并发送,会为每一个数据包启动一个逻辑的定时器。否则要么缓存数据,要么通知上层等待。
- 超时,每一个分组都有自己的逻辑定时器,超时之后,发送方只重传超时的单个分组,并重启其计时器。
- 收到ACK,收到ACK(确认应答)时,如果确认分组序号在窗口内,则SR发送方将那个被确认的分组标记为已接收。如果确认序号等于send_base,则窗口向右侧移动至具有最小序号的未确认分组处。
接收方
- 初始化接收窗口,接收方也会初始化一个长度为N的接收窗口,定义rec_base()。
- 接收到数据包
- 序号在[rec_base,rec_base + N - 1]内,收到的分组序号位于接收窗口内,一个选择ACK会返回给发送方。如果该分组第一次接收,则缓存该分组。如果该分组的序号等于rec_base,则从该序号分组开始到后面连续缓存的分组会被一并交付给上层,窗口也会向右侧移动至第一个未缓存的位置。
- 序号在[rcv_base - N,rcv_base - 1]内,在这个范围内的分组已经被正确接收了,但是有可能返回的ACK信息没有被发送方收到,这个时候需要为此次接收到的分组重新返回一个ACK确认。
- 此外的情况,忽略收到的分组。
需要注意的地方
为什么接收到的数据包序号在[rcv_base - N,rcv_base -1]内时,需要为该分组重新返回确认?
当分组的接收方返回的ACK出现丢失,没有被发送发成功接收时,发送方会重传该分组,如果接收方此时不返回ACK确认,会导致发送发窗口阻塞(发送方会一直重传该分组)。
至于为什么范围是接收方当前窗口前面的N个,可用这样想:接收方一次能够最大移动的距离为N,移动时返回的ACK确认出现丢失的范围为[rcv_base - N,rcv_base -1]。
在SR协议中窗口长度必须小于或者等于序号空间大小的一半。