总览
(建议使用Chrome浏览器安装Imagus插件(点击安装),鼠标指针悬停在链接或缩略图上时直接在当前页面的弹出视图上显示这些图片、HTML5 视频/音频和内容专辑)
可靠数据传输协议
RDT 1.0
RDT 2.0
RDT 2.1
RDT 2.2
RDT 3.0
进步
引入了差错检测,接收方反馈(ACK和NAK)和重传机制
在数据分组中添加一新字段,让发送方对其数据分组编号,即将发送数据分组的序号放在该字段
移除NAK,在ACK中加显式加入被确认分组的序号
同时考虑到丢包和比特受损的情况,在发送方加入了一个倒计数定时器,来解决超时问题
发送方FSM





接收方FSM





问题
将数据的传输信道理想化,视为完全可靠
没有考虑ACK或NAK受损的可能性
没有考虑丢包
没有考虑丢包
效能太低
流水线可靠数据传输协议
GBN(回退N步)
SR(选择重传)
发送方和接收方看到的序号



对失序的分组的处理
不缓存任何失序分组
失序的分组被缓存直到所有丢失分组皆被收到为止
操作


可靠数据传输
要求:数据可以通过一条可靠的信道进行传输,借助于可靠信道,传输数据比特就不会受到损坏或者丢失
可靠数据传输:Reliable Data Transfer,简称RDT或rdt
FSM
有限状态机(Finite-State Machine, FSM)
FSM的箭头指示了协议从一个状态变迁到另一个状态
引起变迁的事件显示在表示变迁的横线上方,事件发生时所采取的动作显示在横线下方
如果对一个事件没有动作,或没有就事件发生而采取了一个动作,我们将在横线上方或下方使用符号Λ(Lambda),以分别明确地表示缺少动作或事件
FSM的初始状态用虚线表示
构造可靠数据传输协议
rdt 1.0
在 1.0 版本中,我们考虑最简单的情况,即底层数据信道是完全可靠的,将数据的传输信道理想化,视为完全可靠,不丢包,不损失比特 ,在这样的情况下,发送端发送数据,接收端直接接收,并不考虑丢包,超时这些问题,发送方和接收方的FSM每个都只有一个状态
发送端:
发送端通过使用rdt_send(data)事件接收来自高层的数据,然后用make_pkt(data)产生一个分组,将分组发送到信道中

接收端:
接收端通过rdt_rcv(packet)事件从底层信道接收一个分组,从分组中取出数据(通过extract(packet,data)动作),并将数据上传给较高层(通过deliver_data(data)动作)

问题:接收方没有提供任何信息反馈给发送方,假定了接收方接收数据的速率能够与发送方发送数据的速率一样快,假定了不出现传输差错。
rdt 2.0
在 rdt2.0 中,我们将传输通道视为有可能发生比特错误,数据在传输中不会发生丢包的现象,但是会存在一部分比特错误的情况,
于是我们引入:
差错检测:使用了检验和(checksum)
接收方反馈:接收方返回ACK或NAK
重传:接收方收到有差错的分组时,发送方将重传该分组文。
发送方:
发送方等待上层传下来的数据然后调用rdt_send(data),产生一个包含待发送数据的分组(sndpkt),带有检验和然后由udt_send(sndpkt)发送该分组。在右边的状态中,发送方等待来自接收方的ACK或者NAK分组,如果收到一个ACK分组,协议返回到等待来自上层数据的状态;如果接收到一个NAK分组,则重传上一个分组并等待接收方为重传分组回送ACK或NAK。

接收方:
分组到达时候,根据分组是否受损回答一个ACK或者NAK。

注意:当发送方处于等待ACK或NAK的状态时,它不能从上层获得更多的数据;也就是说rdt_send()事件不可能出现;仅当接收到ACK并离开该状态时才能发生这样的事件。因此,发送方将不会发送一块新数据,除非发送方确认接收方已正确接收当前分组。由于这种行为,rdt 2.0这样的协议被称为停等(stop-and-wait)协议。
问题:没有考虑到ACK或NAK分组受损的情况,如果一个ACK或NAK分组受损,发送方无法知道接收方是否正确接收了上一块发送的数据
rdt 2.1
该协议在 2.0 基础上增加了一个序号值(对于停等协议,1比特就足够用了,0和1)
发送方:

接收方:
接收方当收到失序的分组时,接收方对所接收的分组返回一个肯定确认,如果收到受损的分组,则返回否定确认

rdt 2.2
在rdt2.1的基础上,不发送NAK,而是再发送一个ACK,则发送方接收到对同一个分组的两个ACK(冗余ACK)后,就知道接收方没有正确接收到跟在被确认两次的分组后的分组。
接收方此时必须由一个ACK报文所确认的分组序号(接收方make_pkt()),发送方此时必须检查接收到的ACK报文中被确认的分组序号(发送方isACK())
发送方:

接收方:

rdt 3.0
可以说,在处理数据出错方面,上面的协议都做得很好了,但是,我们忽略了一个很大的问题,万一数据不是出现错误,而是直接丢失了呢!!这就是我们俗称的丢包了,于是,我们的 rdt3.0 千呼万唤始出来了。
所以在这里,我们假设的是最贴近真实的情况,数据传输通道发送和返回的过程中不仅会出错,而且还会丢包!
为了实现基于时间的重传机制,需要一个倒计数定时器(countdown timer),在一个给定的时间量过期后,可中断发送方。
因此,发送方需要能做到:
每次发送一个分组(包括第一次分组和重传分组)时,便启动一个定时器。
响应定时器中断(采取适当的动作)
终止定时器
发送方:

接收方:
(与rdt2.0接收方相同)

处理分组丢失示意图
无丢包操作

分组丢失

丢失ACK

过早超时

因为分组序号在0和1之间交替,因此rdt3.0有时被称为比特交替协议(alternating-bit protocol)
流水线可靠数据传输协议
前言
rdt 3.0是一个功能正确的协议,但并非人人都对它的性能满意,特别是在今天的高速网络中更是如此。rdt 3.0性能问题的核心在于它是一个停等协议。
流水线(pipelining)
流水线技术对可靠数据传输协议可带来如下影响
必须增加序号范围。因为每个输送中的分组(不计算重传的)必须要有一个唯一的序号,而且也许有多个在输送中的未确认报文。
协议的发送方和接收方两端也许不得不缓存多个分组
所需序号范围和对缓冲的要求取决于数据传输协议如何处理丢失,损坏和延时过大的分组。
解决流水线的差错恢复有两种基本方法:
回退N步(Go-Back-N, GBN)
选择重传(Selective Repeat, SR)
回退N步(GBN)
最大允许数N:在流水线中未确认的分组的个数,(窗口长度)
基序号base:最早未确认分组的序号
下一个序号nextseqnum:最小的未使用序号
[0,base-1]对应了已经发送并被确认的分组;[base,nextseqnum-1]对应已经发送但是未被确认的分组。[nextseqnum,base+N-1]对应那些要被立即发送的分组。大于或等于base+N的序号无法使用

发送方:
响应三种类型的事件
上层的调用。上层调用rdt_send()时,发送方需要检查窗口是否有N个已发送但未确认的分组,如果未满,则发送,已满则向上一层反馈。实际上,发送方可能会缓存这些数据或者与上层采用同步机制。
收到ACK。使用累计确认的方式,表明接收方已正确收到序号为n的以前且包括n的分组。
超时。发送方重传所有已发送但还没被确认的过的分组。

接收方:
如果序号为n的分组被接收到,则返回ACK,并将该分组交付给上层,在其他情况下,丢弃该分组,并为最近的按序接收的分组重新发送ACK。

运行中的GBN

问题
当窗口长度和带宽时延积都很大,在流水线中会有很多分组,一个分组的差错会导致重传很多分组。
选择重传(SR)
让发送方仅重传那些它怀疑在接收方出错的分组而避免了不必要的重传。
发送方:

从上层收到数据。当从上层接收到数据后,SR发送方检查下一个可用于该分组的序号。如果序号位于发送方 的窗口内,则将数据打包并发送;否则就像在GBN中一样,要么将数据缓存,要么将其返回给上层以便以后传输。
超时。定时器再次被用来防止丢失分组。然而,现在每个分组必须拥有其自己的逻辑定时器,因为超时发 生后只能发送一个分组。可以使用单个硬件定时器模拟多个逻辑定时器的操作。
收到ACK。如果收到ACK,倘若该分组序号在窗口内,则SR发送方将那个被确认的分组标记为已接收。 如果该分组的序号等于send_base 则窗口基序号向前移动到具有最小序号的未确认分组处。如果窗口移动了并且 有序号落在窗口内的未发送分组,则发送这些分组。
接收方:

序号在[rcv_base, rcv_base+N-1 ]内的分组被正确接收。在此情况下,收到的分组落在接收方的窗口 内,一个选择ACK被回送给发送方。如果该分组以前没收到过,则缓存该分组。如果该分组的序号等于接收窗口的基序号.则该分组以及以前缓存的序号连续的(起始于rcv_base的)分组交付给上层。然后.接收窗口按向前移动分组的编号向上交付这些分组。
序号在[rcv_base-N,rcv_base-1 ]内的分组被正确分割。在此情况下,必须产生一个ACK,即使该分组 是接收方以前已确认过的分组。
其他情况。忽略该分组。
失序的分组将被缓存直到所有丢失分组(即序号更小的分组)皆被收到为止,这时才可以将一批分组按序交付给上层。
SR操作

1954

被折叠的 条评论
为什么被折叠?



