发送方(S)必须等待接收方(R)回应后才能发送下一个请求。
会出现一下几种情况:
S给R发送的请求可以在请求头中新增一个序列号(Seq),如果Seq重复,那么我们R端可以丢弃,并且做出响应,这个时候如果之前网络延迟导致消息迟到的响应也到达了S,那么我们为了能够让S也知道消息重复,所以我们给响应头增加了个(ACK)]
和停止等待协议类似,不过我们采用分组发送,对于每个分组,我们称之为窗口
在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的大小超过了取值上限
如果超限,如果发送超时重传,此时无法分辨新、旧分组
在这种情况下,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到达后,理所应当
最大值
$$ W_T = W_R = 2^{(3-1)}=4 $$
如果我们设置为5的话呢?
如果在返回确认分组的时候ACK_0丢失,1-4记录为已收到,发动窗口不能移动,等待超时重传
所以这里又发生了问题
所以说这里取值为2^{n-1}是为了避免最后n个出现差错
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。