运输层(二)可靠数据传输原理

前言:

来源于《计算机网络自顶向下方法》,承接上回UDP协议,不可靠的数据传输协议,这回来到了可靠数据传输协议,意味着来到了众所周知的TCP协议了,但是没这么快,先了解一下可靠数据传输原理。其实是因为篇幅太长=。= 跟tcp分开两篇写了

可靠数据传输原理

经完全可靠信道的可靠数据传输:rdt1.0

它基于完全可信的信道来传输数据,传输的过程中不会出现比特错误或者丢包,在这个简单的协议中,一个单元数据和一个分组没差别,而且所有分组都是从发送方流向接收方,有了可靠通道,接收方不必提供任何反馈信息给发送方担心出错。
下图表示了在底层信道完全可靠的情况下,分别对应于发送方和接收方的有限状态机定义:

rdt 的发送端
只通过 rdt_send(data) 事件接收来自较高层的数据发送请求。在完成一次数据发送请求中需要两个动作:

  • 产生一个包含该数据的分组(经由 make_pkt(data) 产生)
  • 然后将该分组通过 udt_send(packet) 发送到信道中

完成这两个动作后,重新返回原始状态,继续等待来自较高层的数据发送请求。

接收端,rdt 通过 rdt_rcv(packet) 事件从底层信道接收一个分组。在一次数据接收过程中同样需要两个动作:

  • 从分组中取出数据(经由 extract(packet, data) 产生)
  • 然后将数据上传给较高层(通过 deliver_data(data) 动作)

经具有比特差别信道的可靠数据传输:rdt2.0

由于具有比特差别,那么我们需要解决的问题就是如何让发送方知道哪些内容被正确接受,哪些内容接受有误,并因此需要重复发送。利用口述报文协议使用肯定确认(ACK)与否定确认(NAK)来解决该问题,在计算机网络中,基于这种重传机制的可靠数据传输协议称为自动重传请(Automatic Repeat Request, ARQ)协议
ARQ协议中还需要另外三种协议功能要处理存在比特差别的情况

  • 差错检测
    需要一种机制以使接收方检测到何时出现比特差别,如udp使用因特网检验和字段正是为了这个目的,这些技术要求有额外的比特从发送方发送到接收方,而这些比特将存放在 rdt 2.0 数据分组的分组检验和字段中。
  • 接收方反馈
    发送方要了解接受方情况,唯一途径就是让接收方提供明确的反馈信息给发送方,在口述报文情况下回答“肯定确认”(ACK)或者“否定确认”(NAK),类似的我们的rdt2.0需要从接收方向发送方会送ack与nak分组,理论上这些分组只需要一个bit长度,用0表示nak,1表示ack
  • 重传
    接受方收到有差别的分组时,发送方将重传该分组文。

下图为rdt2,0分别对应于发送方和接收方的有限状态机定义:
发送端(等待上层传下来数据):

  • 当rdt_send(data)事件出现,发送方将产生一个包含待发送数据的分组,带有检验和
  • 经过udt_send(sndpkt)操作发送该分组。随后进入等待接收方的ack/nak分组状态

发送端(等待接收方的ack/nak分组状态)

  • 收到一个ack分组(rdt_rcv(rcvpkt)&&isACK(rcvpkt)),则发送方知道最近发送的分组已经被正确接受,因此协议返回等待上层传下来数据状态
  • 收到一个nak分组,则该协议重传上一个分组并等待接受ack/nak分组的状态
    注意:当发送方处于等待接受ack或者nak的状态时,它不能从上层获取更多数据。即当前状态不是等待上层传下来数据状态。
    因此,发送方将不会发送一块新数据,除非发送方确信接收方已正确接收当前分组)由于这种行为,rdt2.0这样的协议被称为停等协议。
    但rdt2.0协议存在这一个致命的缺陷:忽略了ack或者nak分组受损的肯能行。
    rdt2.1协议对此的解决方案是在数据分组中新增一个新的字段,让发送方对其数据分组编号。即将发送数据分组的序号放在该字段。接收方只需检测需要即可确认收到的分组是否是一次重新传送。(接收到的分组序号与最近收到的分组号是否相等,相等则是一次重传),**发送端知道所接收到的 ACK 和 NAK 分组(无论是否受损)都是为响应其最近发送的数据分组而生成的。**所以ack和nak分组则不需要指明他们要确认的分组序号
    是 rdt 2.1 发送端的有限状态机描述图:

    现在的状态数是以前的两倍,是因为协议的状态必须反映出目前(由发送端)正发送的分组或(在接收端)希望接收的分组序号是 0 还是 1。
    总结 解决ack受损的场景:就是发送端有两种序号0、1,接收端也是有两种序号0、1,
  • 一开始发送端0发送分组后,转化为等待序号为0的ack,nak分组的状态
  • 接收端0收到分组后转化为接收端1,期待接受序号为1的分组,会送了一个ack报文给发送端
  • 此时ack报文受损,则发送端选择了重新传送一个序号为0的分组
  • 接收端此时期待接受的是序号为1的分组,所以发送一个ack给发送端
  • 发送端此时转化为需要为1,发送下一个分组。

rdt2.2
但是如果不发送 NAK,而是对上次正确接收的分组发送一个 ACK,也能实现与发送 NAK 一样的效果。发送端接收到对同一个分组的两个 ACK(即接收冗余ACK)后,就知道接收端没有正确接收到跟在被确认两次的分组后面的分组。这就是 rdt 2.2 可以取消 NAK 分组的原因。

经具有比特差错的丢包信道的可靠数据传输:rdt3.0

有很多可能的方法用于解决丢包问题,在这里,我们让发送端负责检测和恢复丢包工作。假定发送端传输一个数据分组,该分组或者接收端对该分组的 ACK 发生了丢失。在这两种情况下,发送端都收不到应当到来的接收端的响应。所以,如果发送端愿意等待足够长的时间以确定该分组缺失已丢失,则它只需要重传该数据分组即可。

上图是 rdt3.0 发送方的 FSM 图,就拿右上角的状态举例,此时发送端等待接收方返回的带有“0”序号的 ACK ,它有三种行为:
倒计时定时器:规定时间内,若无反馈,则重传

  • 第一种:过程中未丢包,但是数据比特出错或者不符合序号,和我们讨论过的 rdt2.2 差不多,但是此时无需做处理,只需要等到时间间隔一到,当做超时处理,重发数据
  • 第二种:是真正的丢包了,所以时间一到,重新发送分组。
  • 第三种最理想:啥事没有,一切正常,跳到下一个状态,等待发送下一个包

为了实现基于时间的重传机制,需要一个倒计时计时器,在一个给定的时间量过期后,中断发送端。因此发送端需要能做到:

  • 每次发送一个分组(包括第一次分组和重传分组)时,便启动一个定时器
  • 响应定时器中断(采取适当的动作)
  • 终止定时器

现在 rdt 3.0 已经是一个功能正确的协议,但因为它的本质仍然是停等协议。

总结:

归纳一下可靠数据传输协议的要点:检验和、序号、定时器、肯定和否定确认分组。

你可能感兴趣的:(计算机网络)