这篇文章上次修改于 307 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
  • 计算机网络笔记8——RDT

    可靠数据传输

    可靠数据传输在运输层、链路层、应用层都会出现。

    可靠信道:指在数据传输中,保证数据包不会丢失、损坏或以错误的顺序从端到端的一种通信信道。

    然而实际的底层是不可靠信道,例如底层有概率会丢失,损坏,顺序错误等等,我们需要使用可靠数据传输协议用于保证在上层体现为可靠信道。

    有限状态机(Finite State Machine,FSM)

    是一种模型,用于描述具有有限个状态和状态转移的系统。

    RDT(Reliable Data Transfer)

    rdt1.0

    RDT 1.0是计算机网络课程中引入的最基本的可靠数据传输协议模型。RDT 1.0的设计假设底层网络是可靠信道。这种假设在实际应用中是不现实的。

    RDT 1.0的目的是帮助理解更复杂的可靠数据传输协议的基础。

    接收方和发送方都是FSM。

    发送方:

    1. 从上层应用接收数据。
    2. 封装数据为数据包。
    3. 将数据包发送到接收方。

    接收方:

    1. 从下层网络接收数据包。
    2. 处理数据包中的数据。
    3. 将数据传递到上层应用。

    rdt2.0

    经具有比特差错信道的可靠数据传输

    RDT 2.0引入了错误检测、确认(ACK)和重传机制。这些机制确保了即使在不可靠的信道上(即存在比特错误的信道),数据仍然可以被可靠地传输。

    特性:

    1. 错误检测:使用校验和(checksum)来检测数据包中的比特错误。
    2. 肯定确认(ACK)和否定确认(NAK):接收方在收到数据包后发送ACK或NAK来通知发送方数据包是否正确接收。
    3. 重传机制:如果接收方检测到错误(收到NAK),发送方将重传数据包。

    发送方:

    1. 从上层应用接收数据。
    2. 生成数据包,并计算校验和。
    3. 发送数据包到接收方。
    4. 如果接收到ACK,发送下一个数据包;如果接收到NAK,重传当前数据包。

    接收方:

    1. 接收数据包并计算校验和。
    2. 如果校验和匹配(无错误),发送ACK;如果校验和不匹配(有错误),发送NAK。
    3. 如果数据包无错误,将数据传递到上层应用。

    但rdt2.0没有考虑到ACK或NAK分组受损的可能性。

    解决方法尝试:

    • 如果回复传输有问题,发送方可以再次询问接收方正确的回答。
    • 进行足够多的检验,使发送方不仅可以发现差错,还可以恢复处理。
    • 如果收到出问题的回复,就再发一遍原来的分组,会导致冗余分组,但是接收方无法知道这个新发来的是重发还是新的。因为它不知道自己的回复是否成功发送。

    rdt2.1

    RDT 2.1 在 RDT 2.0 的基础上引入了序列号(Sequence Number)机制,这是其与 RDT 2.0 最显著的不同之处。

    序号只需要1bit,因为它只要让接受者知道这是上一个包还是新的包就可以了。而接受方回复的ACK和ANK不需要序号。

    如果发送方接收到两个一样序号的ACK,就知道自己的上一个数据包没有成功传输。

    rdt2.2

    rdt2. 1和rdt2.2之间的细微变化在于,接收方此时必须包括由一个ACK报 文所确认的分组序号(这可以通过在接收方FSM中,在make.pkt()中包括参数ACK 0或 ACK1来实现),发送方此时必须检查接收到的ACK报文中被确认的分组序号(这可通过 在发送方FSM中,在isACK()中包括参数0或1来实现)。

    rdt3.0

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

    不同于rdt2,rdt3可以解决丢包问题,如果发生丢包,双方都收不到想要的响应。

    我们通常可以想到发送方如果认为超时,就再次发送。设定恰当的重发时间,同时rdt2.2已经解决冗余分组的问题。

    重发时间的实现就是在发送的时候启动一个timer计时器。

    此时我们得到了一个可靠数据传输协议。

    模拟一下情况,如果A发送给B,A发给B的时候丢包,A会在一定时间后再发,如果只是因为传输时间过慢,发送了两个包,B也会对这两个包回复一样的ack,A就知道了之前的包冗余,并且也不需要再处理了。

    流水线可靠数据传输协议

    rdt的问题主要在于它是一个停等协议,在传输后,需要等到回复才会去发送下一包数据,但是不断地发送过程中就有很多的等待状态,效率很低。

    解决:不停等

    允许发送方发送多个分组而无须等待确认,或者理解成一次性多发送几个分组,等待回复。

    影响

    • 此时我们的序号就不能是1和0,需要更大的范围保证能指明到前面的哪个包接受失败。
    • 需要一次性缓存多个分组,不能马上确保某个分组是否传输成功,随时准备重发。

    对丢包解决产生两种方法:回退(go-back-N) 和 选择重传(SR)

    回退协议(GBN 滑动窗口协议)

    概念解释:

    • 发送滑动窗口:发送方维护一个窗口,窗口的大小通常为N,表示可以连续发送的未确认数据包的最大数量。
    • 接收滑动窗口:接收方通常只有一个固定大小为1的窗口,表示每次只接收按顺序到达的一个数据包。
    • 序号:每个数据包都有一个唯一的序号,序号的范围通常是0到(2^k)−1,其中k是分组序号的比特数,所有涉及序号运算都要取模,类似于一个环。
    • 基于ACK无NAK:接收方接收数据包后,会发送一个ACK来确认接收到的数据包。如果接收方接收到的不是期望的下一个数据包,它会丢弃并不予确认。

    工作原理:

    发送方:

    发送窗口内的数据包可以连续发送而无需等待ACK。发送方维护一个基序号(base)和下一个待发送的数据包序号(nextSeqNum)。发送窗口的大小为N,即base,base+N−1。当发送方发送一个数据包时,nextSeqNum增加。发送方启动一个计时器用于未确认数据包的重传。如果在计时器超时之前没有收到ACK,发送方会重传从基序号开始的所有未确认的数据包(回退N步)。

    接收方:

    接收方只接收按序到达的数据包。如果接收到的包的序列号等于期望的序列号,接收方会接收该包并发送ACK。如果接收到的包的序列号不是期望的序列号,接收方会丢弃该包并重传上次发送的ACK。

    示例:

    假设发送窗口大小为4(N=4):

    1. 发送方发送序列号为0, 1, 2, 3的数据包。
    2. 接收方按顺序接收数据包0, 1,并发送ACK0, ACK1。
    3. 发送方收到ACK0, ACK1,将基序号更新为2,并发送序列号为4, 5的数据包。
    4. 如果发送方未收到ACK2并发生超时,发送方将重传序列号2, 3, 4, 5的数据包。

    缺点:

    当窗口长度和带宽时延积都很大时,一个分组的问题可能会引起很多分组的重传。

    选择重传(SR协议)

    我个人感觉选择重传更容易理解。

    发送方

    发送方接收到ACK后,将相应的数据包标记为已确认,并更新发送窗口。

    发送方为每个未确认的数据包启动一个独立的计时器。

    如果计时器超时(即未在规定时间内收到ACK),发送方仅重传超时的数据包。

    接收方

    接收方为每个成功接收的数据包发送ACK,ACK中包含被确认的数据包的序列号。

    接收方可以缓存乱序到达的数据包,等待缺失的数据包到达后按序递交给上层。

    当所有数据包按序到达后,接收窗口滑动以接受新的数据包。