可靠传输的实现机制
停止-等待协议(SW)
参考3.4.1 可靠传输的基本概念哔哩哔哩bilibili
发送方(S)必须等待接收方(R)回应后才能发送下一个请求。
会出现一下几种情况:
- S发送给R,R接收到,R回复,over
- S发送给R,R没有接收到,S超时重传,这里会发生两种情况
- 网络中断,R没有收到,消息丢失,超时重传
- 网络延迟,R收到了,但是这个时候S又发送了一份,那么R就收到了重复数据,那么这种问题如何解决?
S给R发送的请求可以在请求头中新增一个序列号(Seq),如果Seq重复,那么我们R端可以丢弃,并且做出响应,这个时候如果之前网络延迟导致消息迟到的响应也到达了S,那么我们为了能够让S也知道消息重复,所以我们给响应头增加了个(ACK)]
回退N帧协议(GBN Go-Back-N)
和停止等待协议类似,不过我们采用分组发送,对于每个分组,我们称之为窗口
在S端,窗口尺寸我们成为W_T,在R端,窗口尺寸成为W_R
如果我们采用n个比特来对分组进行编号,那么W_T的取值为:1 lt W_T le {2^n-1},W_R的取值为:W_R = 1
假设我们是3个比特位,W_T=5,如图:
滑动窗口
拿正常(无差错)情况来说,S依次连续发送0-4给R,正确到达R,没有乱序和误码,每接收一个接受窗口就向前滑动一个位置,并给S返回接收分组的确认分组,S每收到一个回复,发送窗口也向前移动一个位置,收到确认数据的分组就可以删除
累积确认
R不一定要对接收到的数据分组逐个发送确认,而是在收到几个数据分组后,对按需到达后的最后一个分组进行确认,ACK_N表示序号为n及以前的所有数据分组都已正确接收了。
优点和产生的问题:
如果分为两组累计,.e.g:
{0,1} and {2,3,4}
如果ACK_1丢失了,而ACK_4又返回给了S,那么S就会认为ACK_4以及之前的数据分组都被R正确接受了,滑动窗口前行,旧分组从cache中删除
这里可以说说累计确认的优点之一:即使确认分组丢失,S也可能不必重传,同时减少了R的开销和网络资源占用
但是R不能向S及时反应出R已经正确接受的数据分组信息
如果有差错的情况呢?
比如{5,6,7,0,1},如果5出现了误码,那么丢弃5,而后续代码的序号和接收方窗口的序号不匹配,所以全部丢弃,这个时候依然返回ACK_4,所以S还需要重传,这就是Go-Back-N
可以看到,如果通信线路质量不好,回退N帧信道利用率并不比SW协议高
如果W_T的大小超过了取值上限
如果超限,如果发送超时重传,此时无法分辨新、旧分组
选择重传协议(SR)
- GBN协议设置接受窗口尺寸W_R只能为1,因此R只能按需接受正确到达的数据分组
- 一个数据分组的无码,会导致多组数据超时重传,对通信资源产生极大的浪费 那么能否直冲穿出现误码的分组呢? 因此,接收窗口的尺寸W_R不应该等于1,而应该大于1,编译u接收方先收下失序到达但无无码并且序号落在接收窗口内的那些数据分组,等到所缺分组收齐后再一并送交上层。 这就是选择重传协议(SR) 因为SR协议为了使S仅重传出现差错的分组,接收方不能再采用累计确认,而需要对每个争取接受到的数据分组进行逐一确认!
针对分组丢失
在这种情况下,R中0和1已经接收了,所以返回0和1的确认信息,并发送确认分组,R窗口向前滑动两个位置。
R接受3号分组,并确认,但是R窗口不能向前滑动,因未按序到达
此时将{0,1,3}的确认分组信息返回给S
S处理完0和1后,窗口滑动
此时将{4,5}发送给R,{0,1}从cache中删除,R将{0,1}交付上层处理
S接受3号确认分组,但是S窗口不能向前滑动,同时记录3号分组已收到确认,避免出现超时重传
{4,5}到达R,R发送确认分组,但是R窗口不能滑动
S收到后也不能滑动,但是要记录
如果此时S针对2号数据分组的重传定时器超时了,那么进行重传
2到达后,理所应当
S & R 窗口超限引发的问题
最大值
$$ W_T = W_R = 2^{(3-1)}=4 $$
如果我们设置为5的话呢?
如果在返回确认分组的时候ACK_0丢失,1-4记录为已收到,发动窗口不能移动,等待超时重传
所以这里又发生了问题
所以说这里取值为2^{n-1}是为了避免最后n个出现差错