可靠数据传输原理
🐳可靠性问题不仅仅出现在运输层,同样也是会出现在链路层以及应用层次中,可靠性问题同样也是会被列为🔝TOP10问题。
信道的不可靠特性决定了可靠数据传输协议(rdt)的复杂性
可 靠 数 据 传 输 : 服 务 模 型 与 服 务 实 现 : 可靠数据传输:服务模型与服务实现: 可靠数据传输:服务模型与服务实现:
🐳由于可靠数据传输协议的 下层协议也许是不可靠的,我们可以将较低层直接视为 不可靠的点对点信道
- Rdt_send():被上层应用所调用,将数据交付给接收方的较高层
- udt_send():在不可靠信道上向接收方传输数据,udp(不可靠🙅)
- Rdt_rcv():在接收端,分组从信道的接收端到达的时候,调用rdt_rcv()
- Deliver_data():rdt向较高层交付数据
构造可靠的数据传输协议
逐层渐进的完善我们的协议,一步步变复杂
1.经完全可靠信道的可靠数据传输:rdt1.0
考虑最简单的情况:底层信道是完全可靠的(不会bit error, 不会丢弃分组),称该协议为: rdt1.0。下图显示了发送方与接收方的 **有限状态机(FSM)**的定义。
FSM:基本术语的解释:
FSM中的虚线表示初始状态,实线箭头指示了协议从一个状态变迁到另一个状态
引起状态变迁的事件:显示在横线上方
事件发生时候所采取的状态:显示在横线的下方
如果对于一个事件没有动作或者是没有就事件发生而采取了一个动作,在横线上方或者下方使用符号
𝛬
🐳发送端:
- 通过rat_send(data)事件接收来自较高层次的数据
- 产生一个包含该数据的分组(通过make_pkt(data))
- 然后将分组发送到信道中。因为我们假定信道是完全可靠的(当然,只是假设而已),所以我们只需要发送就可以了(udt_send(packet))
🦭接收端:
- rdt通过rat_rcv(packet)事件从底层信道接收一个分组
- 从分组中取出数据(extract(packet,data))
- 将数据上传给较高层次
经具有比特差错信道的可靠数据传输:rdt2.0
底层的信道更为实际的模型是:分组中的比特可能受损。在分组的传输、传播、缓存的过程中,这种比特差错通常是会出现在网络的物理部件中。
我们假定发送的分组(即使受损了)按照发送的顺序进行接收。
类比通话
假设让我们在通话中向对方传送消息报文,报文接收者在 听到、理解、记下报文之后会反馈:OK!
如果听到了一个含糊不清的话语的时候,可能就会要求发送方进行重述。
口述报文协议采用了 肯定确认和 否定确认,基于这样的传统的机制的可靠数据传输协议成为 自动充传请求协议(ARQ)
基本实现
相对于rdt1.0版本我们为了处理 biterror的情况,为了处理这种情况,我们需要引入三种协议功能进行处理
- 差错检验:一种实现就是使用上篇介绍的UDP中的
校验和检测
,当然不只是这样子的,现在只需要记住我们需要有额外的bit发送到接受方(汇集在数据分组的分组检验和字段)- 接收方反馈:那我们上面通过检验和进行检测了,对了还好,如果发生错误了应该怎么办呢?🧐接收方就需要告诉发送方你给我发送的不对,重新给我发送一份新的吧,这就是“肯定确认” & “否定确认”。理论上,这些分组(只是描述状态)只需要一个Bit
- 重传:接收方接收到有差错的分组的时候,发送方将重传该分组报文
有限状态机(FSM)
发送端:
- 当rdt_send(data)事件出现的时候,发送方将产生一个 包含待发送数据的分组,带有 检验和,然后经由udp_send()发送该分组
- 发送方协议等待来自接收方的ACK或者是NAK分组,1. 如果收到ACK,则代表正确的接收了分组,那么就回到初始状态继续等待上层的数据。 2 .如果收到NAK,那就是没有收到正确的数据,需要进行重传并且继续处于等待ACK或者NAK的状态
- 只有当发送方接收到ACK并且离开该状态了才能够继续发送新的报文,这种行为被称为 停等协议(stop-and-wait)
接收端:
接收方的FSM仅有一种状态,当分组到达的时候,接收方要么回答一个ACK,要么回答一个NAK,这取决于收到的分组是否受损。
Rdt2.0的缺陷
如果ACK/NAK发生错误/被破坏怎么办?🐳🧐
如果发送方收到的消息是含糊不清的就进行重传,为了避免接收方重复接收,发送方给每一个分组增加序列号,如果接收方收到了重复的分组即丢弃掉
rdt2.1
发送方:
接收方
对比2.0
因为我们采用的是 停等协议,因此使用两个序列号就是足够的
Rdt2.2:无NAK消息协议
同rdt2.1的功能相同,但是只使用ACK
ACK消息中 显式的加入被确认分组的序号
接收方通过ACK告诉最后一个被正确接收的分组
当发送方收到重复的ACK之后,采用与NAK相同的的处理动作:重传分组
为什么加入上一个正确接收的分组能代替NAK呢?
假设正在传输序号为1的,接收方传回来的消息是:我上一个正确收到的是序号为0的分组,那么这次发送的序号为1的就是没有被正确收到
Rdt3.0
如果信道既可能发生错误,也可能会丢失分组,肿么办?🧐
“检验和” + “序列号” + ACK + 重传够用吗?
🌰:假如说发送端发送了数据给接收方,在半路就丢失了,那么发送方就会无休止的等待。。。接收方没有收到数据,当然也是等待。。。。。
解决方法:
- 如果没有收到ACK,进行重传(好像遇到事就重传哎。。。)
- 如果分组或者ACK只是延迟而不是丢了:1.重复问题已经解决,通过上文的给发送数据添加 序列号
- 需要定时器, 如果发送完一段时间还没有收到ACK,就进行重发
当重传了或者接收到了上一次的ACK就会重置计时器
示例1(丢包)
- a)就是没有发生错误❌的情况,发送端发送,接收方收到后发送ACK状态,发送端收到后继续下一个包的发送。。
- b)中发送端的pkt1出现了丢失,经过一段时间后(超出了发送端设置的事件),发送方进行重新发送,然后进行等待。。。直到收到接收端的ACK消息后才继续发送新的包
实例2(丢失ACK)
- c)中显示了丢失ACK的情况,发送端发送了pkt1,接收端正确的接收到了pkt1,但是将ACK传送给发送端的时候丢失了。发送端一直没有收到ACK,那么就进行了重传,接收端就收到了 重复的分组PKT1。幸运的是我们有序列号进行判断是否是重复的接收,然后再向发送端发送ACK1(注意是ACK1),直到发送端接收到了ACK1之后才发送新的包
- d)中显示了timeout之后进行重新发送包,但是收到了 迟来的ACK1,发送方既然是收到了ACK1,那么我就继续发送新的包pkt0。同样接收方接收到了 冗余的pkt1,检测到重复了,置之不理。发送方又收到了ACK1(之前都收到过了,因此),置之不理。
Rdt3.0性能分析
因为停等的协议,导致了发送方的利用率:发送方实际忙于将发送比特送进通道的那部分时间与发送时间之比 很低