传输层Transport layer可靠数据传输Reliable data transfer, since 2020-08-05

(2020.08.05)

什么是可靠数据传输(rdt)

可靠传输满足两个条件, i.e., 描述性定义,1) 数据传输过程中无损,2) package的接收顺序和发送顺序相同,即正序

传输层对下层网络层的假设
网络层的数据传输是不可靠的,即数据有比特损坏、数据包丢失、接收错序。

构建可靠数据传输协议
有如下构建过程,1) 由完全可靠信道的rdt,2) 由比特差错信道的rdt,3)由比特差错和丢包信道的rdt。引入Finite State Machine (FSM)有限状态机的分析方法。

1. 完全可靠信道的rdt

发送端sndr,静默状态时等待上层的调用,当上层需要发送数据,则sndr进入rdt_send(data)动作,该动作触发两个动作packet = make_pkt(data)和udt_send(packet),其中udt_send是交给网络层的unidirectional data transfer (udt)。即rdt_send(data) packet = make_pkt(data), udt_send(packet)。
接收端rcvr,静默状态时等待来自下层的调用,当下层接收到数据,则rcvr进入rdt_rcv(data)动作,该动作触发两个动作extract(packet, data)和deliver_data(data)。即rdt_rcv(data) extract(packet, data), delivery_data(data)。

2. 由比特差错信道的rdt

该情况下仅仅假定信道会带来比特差错,而不会导致packet发送顺序的差错。
(2020.08.06)
考虑一下人会怎么处理这种信息。一般来说,接收者会回答一个肯定确认(Positive acknowledgment, ACK)或一个否定确认(Negative acknowledgment, NAK)。这些控制报文会使得接收方可以让发送方知道哪些内容被正确接收,哪些需要重传。计算机网络中基于重传机制的可靠数据传输协议称作自动重传请求(Automatic Repeat reQuest, ARQ)。ARQ需要三种协议功能来处理存在比特差错的情况:

  • 差错检测。需要一个额外的机制使得接收方检测到有差错并能够纠错。该技术需要额外的比特从sndr到rcvr,这些比特被分配到检验和字段中。
  • 接收方反馈。接收方明确的发送ACK或者NAK信息给sndr。理论上这些信息只需要一个比特长,比如0代表NAK,1代表ACK。
  • 重传。rcvr收到了有差错的分组,sndr将重传。

一个重要事实:sndr在发送了数据报之后,等待rcvr的ACK/NAK信息过程中不能从应用层获得更多数据,即不能发送一个新的数据,除非sndr确信rcvr已经正确棘手当前分组。有这种行为的协议称为停等协议(stop-and-wait)

注意到如果数据分组在传输时受损,则ACK/NAK信息也可能在传输时受损,且发送方无法知道接收方是否正确接收了数据报。面对受损的ACK/NAK,有三种情况:

  • 第一种可能,sndr如果不能理解来自rcvr的ACK/NAK信息,可发送一个确认信息,问"你说什么",rcvr接收到这个信息时则复述其回答。但如果这句"你说什么"在传输过程中出问题,则双方都陷入了回答困境。
  • 第二种可能,增加足够的检验和比特,使得sndr(?)可以检测并纠正差错。对于会产生差错但不会丢包的信道来说,这可以直接解决问题。
  • 第三种可能,sndr接收到ACK/NAK含混不清,只需要重传当前数据报,也就是引入了冗余分组(duplicate packet)。冗余分组的问题在于rcvr不知道其上次发送的ACK/NAK数据是否被sndr接收到,也就无法知道收到的冗余分组是新的数据还是上次的重传。

受损的ACK/NAK问题,一个简单的解决方案是在数据分组中添加一个新字段,让sndr对其数据分组编号,也就是将数据分组的序号(sequence number, seq)放在这个字段。因此,rcvr可根据该序号判断收到的分组是否是冗余。目前假定信道不丢失分组,对于停等协议,只用一个比特作为序号,ACK/NAK本身不需要指明他们所确认的seq,sndr也知道该ACK/NAK分组无论是否含混不清,是为响应其最近发送的数据分组。

关于ACK/NAK的区分。当rcvr收到了受损的分组,发送一个NAK给sndr,sndr重发该分组。如果不发送NAK,仅需要对上次正确接收的分组发送一个ACK,也能实现和NAK一样的效果。sndr接收到同一个分组的两个ACK (duplicate ACK),就可知rcvr没有正确接收被确认两次之后的那个分组。rcvr此时发送的ACK中需要包含最后一个正确接收的报文seq。

3. 有比特差错的丢包信道的rdt

在情况1和2的基础上,面对丢包的信道还要考虑两个问题,1)怎样检测丢包和2)丢包后应该如何处理。

发送方sndr负责检测和恢复丢包的工作。sndr在两种情况下认为丢包:

  • pkt在发送过程中丢失
  • rcvr接收到pkt后发送的ACK在发送过程中丢失

这两种情况下sndr都确定数据丢失,只需要在确信数据丢失后重新传输数据即可。所以下一个关键问题是需要等待多久重传。重传的数据称为冗余数据分组(duplicate data packet)。引入重传也就引入了倒计时定时器(countdown timer),该timer在发送一条分组(不管是第一次发送还是重传)之后就会触发。

注:在引入了重传之后,重传的原因除了pkt丢失和ACK丢失,还有一个是超时的时延过短。

流水线可靠数据传输协议

我们计算停等协议的信道利用率(utilization)。一个数据分组的传输时间,其中的也就是每个分组1000个字节的长度,即信道的发送速率是,有。因为使用了停等协议,数据从sndr到rcvr再返回共用时,之后sndr才会发送第二条信息或重传。其中的,我们假设用了,数据从sndr发送到rcvr(忽略接收时间)并且ACK返回给sndr(ACK长度忽略)。因此利用率有:

计算得到,可见信道的利用率是非常低。
解决方案:不以停等协议发送信息,允许sndr连续发送多个分组求无需等待确认,该技术称为流水线(pipelining)。

流水线技术对rdt协议的影响

  • 增加序号seq的范围,每个输送中的分组必须有一个唯一的seq。
  • sndr和rcvr两端都需要设置缓存buffer用于缓存待发送或接收到的分组。sndr buffer的最低限度是能够缓冲那些已发送但未被确认的分组,rcvr buffer或许也需要缓存那些已经正确接收的分组。
  • seq范围和buffer的要求取决于协议如何处理丢失、损坏、延时过大的分组。解决流水线的差错恢复有两种基本方法:回退N步(Go-Back-N, GBN)选择重传(Selective Repeat, SR)

(2020.08.07 Fri)

回退N步(GBN)协议

对于通过运输层发送的分组序列,定义这样三个量。1.基序号base,最早未收到确认(ACK)的分组的序号。下一个序号next_seq,下一个待发送的分组,也就是最小未被使用的序号。窗口长度N,定义了放在sndr buffer中的数据长度。分析可知,如果序号在[0,base-1]则该分组已经发送并收到ACK,序号[base, next_seq-1]对应了已经发送但没收到ACK的分组,[next_seq, base+N-1]对应了在buffer中还没有被发送的分组,[base+N,...]对应了还没有被发送且没有进入buffer的分组。因为滑动窗口N的存在,GBN也被称为滑动窗口协议(sliding window protocol)

在实践中,一个分组的seq承载在分组header的一个固定长度的字段中,其比特数为k,则范围在之间,所有涉及序号的运算必须使用模运算。注意到在TCP中,序号seq是按字节流中的字节进行计数,而非按分组计数。

GBN发送方必须响应的三个事件

  1. 上层调用:sndr的应用层发送数据,启动rdt_send()事件。检察发送窗口N是否已满,即是否有N个已发送但未收到ACK的分组(?表述错误)。窗口未满则产生一个分组并将其发送(?放进滑动窗口),并更新相应变量。如果窗口满,上层等待。实际操作中,sndr可能会缓存这些数据,或使用同步机制(如一个信号量)允许上层仅当窗口不满时调用rdt_send()。
  2. 收到ACK。GBN协议中,序号的n的分组确认采取累计确认(cumulative acknowledgment),表明接收方已经正确接收到序号为n和n以前的所有分组。接收方rcvr的动作:一个seq为n的分组被正确接收,并且按序,即上次交付给上层的数据序号为n-1,则rcvr发送一个ACK,并将seq为n的分组交付给上层。所有其他情况下rcvr都抛弃该分组,也就是丢弃所有失序分组,并为按序接收的分组重新发送ACK,也就是上一次成功接收的分组。丢弃失序分组的方法,对接收方来说优点是接收缓存简单,实际上不需要缓存任何失序分组。
  3. 超时事件。出现超时,sndr重传所有发送但未被确认的分组。sndr仅使用一个timer,作为最早的已发送但未被确认的分组的timer。如果收到一个ACK,但仍有发送而未被确认的分组,则timer重启。
选择重传(selective repeat, SR)

让发送方仅重传那些它怀疑在接收方出错(丢失或受损)的分组而避免了不必要的重传。重传动作从sndr和rcvr两部分。

  • sndr:
    • 从上层接收数据,查看窗口N的情况,如果有空位,则拿出放在窗口中,如果满,则返回
    • 超时。
    • 收到ACK。收到ACK,如果其序号seq在窗口内,则SR发送方将被确认的分组标记为已经接收。如果该分组的序号等于send_base,则窗口基序号base向前移动到未被确认的分组中具有最小序号seq的分组处。如果窗口移动并且有序号落在窗口内的未发送送分组,则发送该分组。
  • rcvr:
    • 序号在[rcv_base,rcv_base+N-1]内的分组被正确接收。在此情况下,收到的分组落在窗口内,发送该分组的ACK给sndr。如果该分组以前没有收到过,则缓存该分组。如果该分组的seq等于窗口的基序号rcv_base,则该分组以及以前缓存的连续序号的分组(始于rcv_base)交付给上层,且接收窗口按向前移动分组的编号向上交付。
    • 序号在上面定义的窗口内的分组被正确接收,产生ACK,即使该分组是rcvr之前已经确认过的分组。
    • 其他情况。忽略分组。

注意,1) sndr和rcvr的窗口并不总是一致,2) 窗口长度必须不大于序号空间的一半。


你可能感兴趣的:(传输层Transport layer可靠数据传输Reliable data transfer, since 2020-08-05)