TCP 详解 ---- 可靠数据传输原理(二)

本贴最后更新于 3815 天前,其中的信息可能已经时移俗易

一问题:如何在不可靠的信道上构造可靠的数据传输协议?

二情景:网络层(尽力而为交付服务,所以网络层是不可靠的)

首先看下图为可靠数据传输框架(下面的图画的丑了点,请将就着看。如果你有什么好的画图工具,请通过评论告诉我谢谢。)

tcp-reliabledatatransfer.PNG

a)图表示在可靠的信道传输数据。一个进程发送数据,一个进程接受数据。数据不会丢失(理想情况,呵呵)。

b)表示上层应用调用rdt_send()可靠传输协议,然后然后转换为分组。调用udt_send()发送分组给对方。在接受方,当分组从信道的接收端抵达时,将调用rdt_rcv()。当rdt协议想向较高层交付数据时,通过调用deliver_data()完成。

以上为可靠数据传输:服务模型与服务实现。

1、完全可靠的信道上的可靠数据传输:rdt:1.0如下图所示

在分析rdt1.0之前,我们需要理解一个概念 有限状态机,引起变迁的事件显示在表示变迁的横线上方,事件发生时所采取的动作显示在横线下方。如果对一个事件没有发生动作,横线下是空白。

rdt的发送方只通过rdt_send(data)从较高层接受的数据,产生一个包含该数据的分组(经由make_pkt(data)动作),并将分组发送到信道中。实际上rdt_send(data)是由较高层的应用调用产生的。

在接收方rdt通过rdt_rcv(packet)事件从底层信道接受一个分组,从分组中取出数据,经由(extract(packet,data)动作,并将数据上传给较高层(通过deliver_data(data)动作)。实际上,rdt_rcv(packet)事件是由叫底层协议过程调用的。

在这个简单的协议中,因为是可靠的信道,所以发送数据的速率和接受数据的速率是一样的。

rdt1.0

 

2、具有比特差错信道上的可靠数据传输:rdt:2.0如下图所示

在分组的传输、传播或缓存的过程中,这种比特差错通信经常出现在网络的物理部件中。我们继续假定所有的传输分组(虽然比特可能受损)将按其发送的顺序接受。

(现实中,人们处理情景)通常情况下,报文接受者在听到,明白记下每句话可能会说“ok”。如果消息接受者听到一句含糊不清的话,他可能要求你重复刚才那句话,这种口述消息协议使用了肯定确认(“ok”)和否定确认(“请重复确认”)这些报文控制使接收方可以让发送方知道那些消息被正确接受,那些需要重传。在计算机网络中。这种基于重传机制的可靠传输协议称为自动重传请求协议(ARQ)。

通常情况下,ARQ协议还需要另外三种协议来处理存在的比特差错。

  • 差错监测。首先需要一种机制以使接收方检测到何时出现了比特差错。目前我们只需知道这些技术要求有额外的比特(除了待发送的初始数据比特之外的比特)
  • 接收方反馈。因为发送方和接收方在不同的端系统上执行,可能相隔数千英里,发送方要了解接收方的情况(即分组是否被正确的接受)的唯一途径就是让接收方提供明确的反馈信息给发送方。口述消息中回答的肯定确认(ACK)和否定确认(NAK)就是这种反馈的例子。rdt2.0协议将从接收方向发送方发送ACK和NAK扥组。理论上。这些分组只需要一个比特的长度。用0表示NAK,用1表示ACK。这里留一个问题:如果发送的NAK或者ACK分组也发送失败该怎么办?接受方一直等待?还是?
  • 重传。接收方收到有差错的分组时,发送方将重传该分组。

rdt2.0-1

rdt2.0-2

      rdt发送方有两个状态。在左边的状态中,发送方协议正等待来自上层的数据。当rdt_send(data)事件发生时,发送方将产生一个包含待发送数据的分组(sndpkt),计算出校验和(checksum),然后经由udt_send(pkt)操作发送该分组。在最右边的状态中,发送方协议等待接收方的ACK或者NAK分组。如果收到一个ACK分组(图中符号为rdt_rcv(rcvpkt)&&isACK(rcvpkt)对应该事件),则发送方知道最近传输的分组已经被正确接受,因此协议返回等待来自上层数据状态。如果收到一个NAK分组,该协议重传最后一个分组并等待接受方返回响应重传分组的ACK或NAK。注意,当发送方在wait-for-or-NAK状态时,它不能从上层获得更多的数据;这就是说,rdt_send()事件不可能出现;仅当接收到ACK并离开改状态时接收方才能继续获取数据。(这会带来什么问题?)。因此发送方将不会发送一块新数据,直到发送方确信接收方已经正确的收到分组为止。这种行为,被称为停等协议。

     rdt2.0接收方的有限状态机任然只有一个状态。当分组到达时,接收方要么回答一个ACK,或者NAK,这取决于分组是否受损。符号rdt_rcv(rcvpkt)&&corrupt(rcvpkt)对应于收到一个分组并发现有错的事件。

2.1、当ACK或者NAK分组受损情景分析,以及初步解决方案:

在rdt2.0协议,存在一个致命的缺陷。因为我们没有考虑到ACK或者NAK分组受损的可能性。当然可以在ACK或者NAK分组中添加检验和比特 以检测这样的错误。更难的问题是,协议应该怎样纠正ACK或NAK分组中的差错。这里的难点在于如果ACK或者NAK分组受损,发送方无法知道接收方是否正确的接收到上一块发送的数据。

 处理受损ACK或NAK时需要考虑以下三种可能性:

  • 第一种可能是,考虑在口述消息的情况下人们的做法。如果说话者不明白受话者的说的ok或者请重复一遍是什么意思?那么说话者接下来可能会问,你说什么?那么接下来就会使情况变的更加复杂。
  • 第二种可能是增加足够的检验和比特,使发送方不仅可以检测比特差错,还可以恢复比特差错。对于会产生差错但不会丢失分组的信道,这就可以解决问题。
  • 当发送方收到含糊不清的ACK或者NAK分组时,只需重发当前的数据分组即可。然而这种方法在发送方到接收方的信道中引入的冗余分组,冗余分组的困难在于,接收方不知道ACK或者NAK是否被接收方收到,也不知道接收到的分组是新的还是一次重传

解决这种问题的方法是(几乎所有的协议都实现了这种方式),在数据字段中添加一个新的字段,让发送方对其数据分组编号,即将发送的数据编号都放入该字段。于是接收方只需要检查序号即可确定收到的分组是否是一次重传。地域停等协议这种简单情况,1比特序号就够了。

rdt2.1-1

rdt2.1-1

rdt2.2是在具有比特差错信道上实现的一个无NAK的可靠数据传输协议,如下图。rdt2.1和rdt2.2之间的细微变化在于,接收方必须包括由一个ACK报文确认的分组序号(这可以通过在接收方FSM中,包括make_pkt()中的参数ACK,0或ACK,1来实现)发送方必须检查接收到的ACK报文中所确认的分组序号(这可以通过发送方FSM中,包括isACK()中的参数0或1来实现)

 

 

rdt2.2-1

rdt2.2-2

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

现在假定除了比特受损外,底层信道还会丢包,这在今天的计算机网络(包括因特网)中并不罕见,该协议喜爱你在必须解决另外两个广泛关注的话题:怎样检测丢包以及发送丢包后该做些什么。利用rdt2.2中已经研发的技术,如校验和,序号,ACK分组和重传等,可以解决后一个问题,为解决广泛关注的的前一个问题。还需增加一种新的协议机制。

有很多方法可以解决丢包问题,这里让发送方负责监测和恢复丢包。假定发送方传输一个数据分组,或者该分组或者接受方对该分组ACK发生了丢失。在这两种情况下,发送方都收不到应当到来的接收方的响应。如果发送方愿意等待最够长的时间以确定分组已经丢失。则只需要重传该数据分组即可,你应该相信该协议确实有效。大部分情况,需要发送方到接收方之间的一个往返时延(可能会包括在中间路由器的缓冲时延)加上接收方处理一个分组所需的时间。在很多网络中,最坏情况下的最大时延是很难估算的,能确定的因素非常少。此外理想的协议应尽可能快的从丢包中理想地恢复出来,而等待一个最坏情况的时延可能意味着要等待一段较长的时间,知道启动差错恢复为止。因此,实际中发送方采取的方法是“明智的”地选择一个时间值,以判断虽然不能确保,但可能发生了丢包。如果在这个时间值内没有收到ACK,即重传分组。注意到如果一个分组经历了一个特别大的时延,发送方坑内会重传该分组。这将会带来一个新的问题?请思考?

rdt3.0的发送方FSM,这是一个在可能出错和丢包的信道上可靠传输数据协议。下图展示了采用定时器的机制,在一个给定的时间过期后,可中断发送方。因此,发送方需要能做到:1.每次发送一个分组(即第一次分组和重传分组)时,便启动一个定时器;2.响应定时器中断。3.终止定时器

 

rdt3.0-1

总结:归纳一下数据传输协议的要点。在检验和、序号、定时器、肯定确认和否定确认分组这些技术中,每种机制都在协议的运行中起到必不可少的作用。因此就会得到一个可靠的数据传输协议。

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...