通信双方如何保证消息不丢失?

1 介绍

数据在传输的时候是分割成一小块一小块传输的,我们把这一小块的数据称之为一个分组。我们在传输这块分组的时候,主要面临两个问题。

  1. 这个分组在传输的过程中,由于在信道传输过程中,收到干扰,导致这个分组到达目的地紫火出现差错,例如分组里面的二进制位1变成0,0变成1.
  2. 分组还没传递到目的地,就丢失了,即分组传到目的地之后出现了差错。

1.1 分组出差错时的处理

这里我们先假设计算机A给计算机B发送分组数据。

  1. 我们可以在分组里放上校验码,当计算机B收到时,就可以根据校验码知道这个分组是否知道差错了。
  2. 如果没有差错的话,计算机B就给计算机A发送一个ACK分组。告诉对方,数据正确无误。如果出现差错的话,就给对方发送一个NAK分组,告诉对方,分组数据出现了差错。
  3. 当计算机A收到接收方(计算机B)的反馈之后,如果收到的是ACK分组,那么就继续发送下一个分组数据。如果收到的是NAK分组,那么久重新传输这个分组。

那么如果计算机B反馈的ACK或者NCK分组也出现了差错呢?

  • 这时A就不清楚B是否正确接收分组了。

  • 那A可以发个NAK告诉B他没有收到正确的分组。

如果A发送的NAK分组也出现了差错呢?

这时就会出现了混乱,就相当于两个人A,B在对话。

A : 传输给你一个分组

B :你发的是啥,可以重发一次吗?

A :你发的又是啥?可以重发一次吗?

B :你发的又是啥?可以重发一次吗

解决方法:当B发送的ACK或NCJ出现差错。A分辨不出来的时候,A就直接重新发送该分组。

那么B收到分组之后,怎么知道这是一个新的分组还是重传的分组呢?

我们可以给每个分组添加一个序号,这样就可以知道是重传的分组还是新的分组了。

如果B收到的分组没出差错,这时又收到一个序号相同的分组,这时B就知道这个分组是属于重传的分组了,这时B就把这个重传的分组丢弃。

1.2 分组丢失的问题处理

可以采取和分组差错类似的方法,如果A迟迟没有收到B的反馈,A就可以认为这个分组丢失了,重新发送。

所以我们每次发送分组的时候,需要给该分组设置一个定时器

在上面问题中,都是A发送一个分组,收到B的反馈之后,再发送下一个分组。在这个等待的过程中一直闲着,信道的大部分也闲着,确实有点浪费资源。

1.3 流水线的方法传递数据,提高传递的效率

如果同时发送多个分组时,最需要处理的问题就是接受方收到分组时,并非按照顺序收到分组的,有可能序号小的分组先达到,这时就会出现了乱序。

1.3.1 回退N步协议

回退N步法中允许发送多个分组而不需要等待确认,但它也受限于在流水线中未确认的分组数不能超过某个最大允许数N。如下图,我们将基序号定义为最早的未确认分组的序号,将下一个序号(nextseqnum)定义为最小的未使用序号(即下一个待发送分组)。

在这里插入图片描述
此时我们可以将序号分成4段。在[0, base-1]段内的序号对应已发送并且已经确认的分组序号,[base,nextseqnum]段内对应已经发送但未确认的分组序号,[nextseqnum, base+N-1]段内表示即将要被发送的分组序号。而那些大于base+N的序号目前还不能使用,直到当前流水线中未被确认的分组得到确认,窗口整体向右移动之后,才能够被使用。

所以,我们常把N称之为窗口长度,由于窗口在序号范围内移动,也被GBN协议称之为滑动窗口协议

对于GBN协议,计算机A(发送方)需要响应以下两个事件:

  1. 收到一个ACK:在GBN协议中,对序号为n的分组的确认采取累计确认的方式。也就是说,当A收到序号为n的分组时,表明分组n以及n之前的分组已经被B正确接受了。

  2. 超时事件: 当久久没有收到ACK时,A就认为它发送的分组已经丢失了,这时A会重传所有已发送但还未被确认的分组。这个时候需要注意的是,并不是为每个分组设置一个定时器,而是在序号[base,nextseqnum-1]中,设置一个定时器,当base发送的那一刻,就开始计时,当收到一个ACK时,则刷新重新开始计时。

计算机B(接收方)则需要处理一下事件:

如果一个序号为n的分组被正确收到,并且按序(所谓按序就是指n-1的分组也已经收到了),则B为分组n发送一个ACK,否则,丢弃该分组,并且为最近按序接收的分组重新发送ACK。

接收方的这种处理方式,意味着如果n被正确交付,则意味着比n小的所有分组也被正确交付了。

如果n-1没收到,却收到了n,这时接收方会被n丢弃。为什么要把n丢弃呢?

  • 因为我们必须把分组按照素心交给上一层(应用层),不然一个一个分组拼凑起来就乱了。
  • 那么我们可不可以先把n缓存起来?然后等收到n-1时,再给n发送ACK。这时不用为n-1发送ACK。
  • 不过如果分组n-1丢失了,那么按照GBN的重传规则,这时n-1和n都会被重传,这时之前缓存的n就没啥用了。而且,我们如果把n丢弃了,那么我们就不需要缓存任何失序的分组了,这样可以让我们的设计更加简单哦。

1.3.2 选择重传(SR)

回退N步协议的缺点也是很明显的,单个分组的差错能够引起GBN重传大量的分组,而且许多分组根本就没有必要重传。例如我们发送的序号为0-100,万一序号为1的分组出现了某些差错,这会导致1-100的分组会被重传,想想这是多么恐怖的事情啊。

因此,出现了选择重传这种协议。所谓“选择”,也就是有选择着去重传。

不过选择重传和回退N步是很相似的,只是在选择重传中,接收方收到失序的分组时,会把它缓存起来,直到拼凑到分组按序,才把分组传输给上一层。而发送方会为每个分组设置一个定时器,这样,只需要重传那些没有被接收方正确接收的分组就可以了。

假设窗口长度N=6,这时A向B发送分组1-5。

在这里插入图片描述
当A收到序号为3的ACK,则状态如下:

在这里插入图片描述
注意,这个时候虽然序号3被确认接收了,但窗口并不能向右移动一格。

接下来受到序号为1的ACK,则:
在这里插入图片描述
这个时候窗口才可以向右移动一格。注意,黄色的那些序号是可以继续发送分组的,只是我没有继续填充发送而已。

接着收到序号为2的分组。
在这里插入图片描述
这个时候窗口向右移动了两个格。

接着继续这样接收下去,如果还有分组没发送的,就从nextseqnum开始填充发送…

如果某个分组超时了,就重新传输这个分组。

对于接收方B的窗口来说也差不多。接收方对于失序的分组缓存起来,直到所有丢失的分组全部被收到为止,再把这批分组按序交付给上一层。

在这里插入图片描述

在这里插入图片描述

那么N是不是越大越好?

  • 不是的,N这个值的大小主要和网络的拥塞情况有关。

这样,两个完全陌生的计算机就可以就行可靠数据传输了。这也是可靠数据传输的原理。

参考:https://www.iamshuaidi.com/749.html

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值