这篇文章上次修改于 307 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
-
计算机网络笔记8——RDT
可靠数据传输
可靠数据传输在运输层、链路层、应用层都会出现。
可靠信道:指在数据传输中,保证数据包不会丢失、损坏或以错误的顺序从端到端的一种通信信道。
然而实际的底层是不可靠信道,例如底层有概率会丢失,损坏,顺序错误等等,我们需要使用可靠数据传输协议用于保证在上层体现为可靠信道。
有限状态机(Finite State Machine,FSM)
是一种模型,用于描述具有有限个状态和状态转移的系统。
RDT(Reliable Data Transfer)
rdt1.0
RDT 1.0是计算机网络课程中引入的最基本的可靠数据传输协议模型。RDT 1.0的设计假设底层网络是可靠信道。这种假设在实际应用中是不现实的。
RDT 1.0的目的是帮助理解更复杂的可靠数据传输协议的基础。
接收方和发送方都是FSM。
发送方:
- 从上层应用接收数据。
- 封装数据为数据包。
- 将数据包发送到接收方。
接收方:
- 从下层网络接收数据包。
- 处理数据包中的数据。
- 将数据传递到上层应用。
rdt2.0
经具有比特差错信道的可靠数据传输
RDT 2.0引入了错误检测、确认(ACK)和重传机制。这些机制确保了即使在不可靠的信道上(即存在比特错误的信道),数据仍然可以被可靠地传输。
特性:
- 错误检测:使用校验和(checksum)来检测数据包中的比特错误。
- 肯定确认(ACK)和否定确认(NAK):接收方在收到数据包后发送ACK或NAK来通知发送方数据包是否正确接收。
- 重传机制:如果接收方检测到错误(收到NAK),发送方将重传数据包。
发送方:
- 从上层应用接收数据。
- 生成数据包,并计算校验和。
- 发送数据包到接收方。
- 如果接收到ACK,发送下一个数据包;如果接收到NAK,重传当前数据包。
接收方:
- 接收数据包并计算校验和。
- 如果校验和匹配(无错误),发送ACK;如果校验和不匹配(有错误),发送NAK。
- 如果数据包无错误,将数据传递到上层应用。
但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):
- 发送方发送序列号为0, 1, 2, 3的数据包。
- 接收方按顺序接收数据包0, 1,并发送ACK0, ACK1。
- 发送方收到ACK0, ACK1,将基序号更新为2,并发送序列号为4, 5的数据包。
- 如果发送方未收到ACK2并发生超时,发送方将重传序列号2, 3, 4, 5的数据包。
缺点:
当窗口长度和带宽时延积都很大时,一个分组的问题可能会引起很多分组的重传。
选择重传(SR协议)
我个人感觉选择重传更容易理解。
发送方
发送方接收到ACK后,将相应的数据包标记为已确认,并更新发送窗口。
发送方为每个未确认的数据包启动一个独立的计时器。
如果计时器超时(即未在规定时间内收到ACK),发送方仅重传超时的数据包。
接收方
接收方为每个成功接收的数据包发送ACK,ACK中包含被确认的数据包的序列号。
接收方可以缓存乱序到达的数据包,等待缺失的数据包到达后按序递交给上层。
当所有数据包按序到达后,接收窗口滑动以接受新的数据包。