TCP/IP卷一:63---TCP基础之(ARQ和重传、分组窗口和滑动窗口、流量控制和拥塞控制、设置重传超时)
发布日期:2021-06-29 22:33:07 浏览次数:4 分类:技术文章

本文共 5044 字,大约阅读时间需要 16 分钟。

一、前言

  • 到目前为止,我们一直在讨论那些自身不包含可靠传递数据机制的协议
  • 它们可能会使用一种像校验和或CRC这样的数学函数来检测接收到的有差错的数据,但是它们不尝试去纠正差错
  • 对于IP和UDP,根本没有实现差错纠正。对于以太网和基于其上的其他协议,协议提供一定次数的重试,如果还是不成功则放弃

信息理论与编码理论

  • 通信媒介可能会丢失或改变被传递的消息,在这种环境下的通信问题已经被研究了多年。关于这个课题的一些最重要的理论工作由克劳德·香农在1948年给出[S48]。这些工作普及了术语“比特”,并成为信息理论( information theory)领域的基础,帮助我们理解了在 一个有损(可能会删除或改变比特)信道里可通过的信息量的根本限制
  • 信息理论与编码理论的领域密切相关,编码理论提供不同的信息编码手段,从而使得信息能在通信信道里尽量免于出错
    • 使用差错校正码(基本上是添加一些冗余的比特,使得即使某 些比特被毁,真实的信息也可以被恢复过来)来纠正通信问题是处理差错的一种非常重要的 方法
    • 另一种方法是简单地“尝试重新发送”,直到信息最终被接收。这种方法,称为自动重复请求(AutomaticRepeatRequest, ARQ),构成了许多通信协议的基础,包括TCP在内

二、ARQ和重传

  • 如果我们考虑的不只是单个通信信道,而是几个的多跳级联,我们会发现不只会碰到前面提到的那几种差错类型(分组比特差错),而且还会有更多其他的类型。这些问题可能发生在中间路由器上,是几种在讨论IP时会遇到的问题:分组重新排序,分组复制,分组泯灭(丢失)。为在多跳通信信道(例如IP)上使用而设计的带纠错的协议必须要处理这些问题
  • 现在让我们来探讨能处理这些问题的协议机制。在概括性地讨论这些之后,我们会探究它们是如何被TCP在互联网上使用的

重传

  • 一个直接处理分组丢失(和比特差错)的方法是重发分组直到它被正确接收。这需要一 种方法来判断:
    • (1)接收方是否已收到分组
    • (2)接收方接收到的分组是否与之前发送方发送的一样。接收方给发送方发信号以确定自己已经接收到一个分组,这种方法称为确认(acknowledgment),或ACK。最基本的形式是,发送方发送一个分组,然后等待一个ACK。当接收方接收到这个分组时,它发送对应的ACK。当发送方接收到这个ACK,它再发送另 一个分组,这个过程就这样继续
  • 这里我们会遇到一些问题:
    • (1)发送方对一个ACK应该等待多长时间?
      • 第一个问题其实挺深奥的。决定去等待多长时间与发送方期待为一个ACK等待多长时间有关。现在确定这个时间可能比较困难,因此我们推迟对这个投术的讨论,直到我们在后面(TCP超时与重传文章)详细讨论
    • (2)如果ACK丢失了怎么办?
      • 第二个问题比较容易:如果一个ACK丢失了,发送方不能轻易地把这种情况与原分组丢失的情况区分开来,所以它简单地再次发送原分组。当然,这样的话,接收方可能会接收到两个或更多的拷贝,因此它必须准备好处理这种情况(见下面的序列号)
    • (3)如果分组被接收到了,但是里面有错怎么办?
      • 至于第三个问题,我们可以借助在上面提到的编码技术来解决。使用编码来检测一个大的分组中的差错(有很大的概率)一般都很简单,仅使用比其自身小很多的一些比特即可纠正。更简单的编码一般不能纠正差错,但是能检测它们。这就是校验和与CRC会如此受欢迎的原因。然后,为了检测分组里的差错,我们使用一种校验和形式。当一个接收方接收到一个含有差错的分组时,它不发送ACK。最后,发送方重发完整到达的无差错的分组

序列号(分组的重复副本)

  • 到目前为止即使这种简单的场景,接收方都可能接收到被传送分组的重复副本。这个问题要使用序列号(sequence number)来处理
  • 基本上,在被源端发送时,每个唯一的分组都有一个新的序列号,这个序列号由分组自身一直携带着。接收方可以使用这个序列号来判断它是否已经见过这个分组,如果见过则丢弃它

三、吞吐量

  • 到目前为止介绍的协议是可靠的,但效率不太高
  • 如果从发送方到接收方传递即使一个很小的分组都要用很长时间(推迟或延迟)的话(如一秒或两秒,对卫星链路来说并非不正常),考虑一下那会怎样
  • 发送方可以注入一个分组到通信路径,然后停下来等待直到它收到ACK。这个协议因此被称为“停止和等待”:
    • 假设没有分组在传输中丢失和无可挽回地损害,该协议的吞吐量性能(每单位时间发送在网络中的数据量)与M/R成正比,M是分组大小,R是往返时间(RTT)
    • 如果有分组丢失和损害的话,情况甚至更糟糕:“吞吐质” (每单位时间传送的有用数据量)明显要比吞吐量要低

无错误的分组情况下吞吐量低的原因

  • 对于不会损害和丢失太多分组的网络来说,低吞吐量的原因是网络经常没有处于繁忙 状态。情况与使用装配流水线时不出一个完整产品就不准新的工作进人类似。流水线大部分时间是空闲的。我们进一步对比,很明显,如果我们允许同一时间有多个工作单元进人流水线,就可以做得更好。对网络通信来说也是一样的一如果我们允许多个分组进人网络,就 可以使它“更繁忙”,从而得到更高的吞吐量

三、分组窗口和滑动窗口

引入窗口机制的原因

  • 很明显,允许多个分组同时进人网络使事情变得复杂
    • 现在发送方必须不仅要决定什么时间注入一个分组到网络中,还要考虑注入多少个
    • 并且必须要指出在等待ACK时,怎样维持计时器,同时还必须要保存每个还没确认的分组的一个副本以防需要重传
    • 接收方需要有一个更复杂的ACk机制:可以区分哪些分组已经收到,哪些还没有。接收方可能需要一个更复杂的缓存(分组保存)机制一允许维护“次序杂乱”的分组(那些比预想要先到的分组更早到达的分组,因为丢包和次序重排的原因),除非简单地抛弃这些分组,而这样做是很没效率的
  • 还有其他一些没有这么明显的问题:
    • 如果接收方的接收速率比发送方的发送速率要慢怎么办?
    • 如果发送方简单地以很高的速率发送很多分组,接收方可能会因处理或内存的限制而丢掉这些分组
    • 中间的路由器也会有相同的问题。如果网络基础设施处理不了发送方和接收方想要使用的数据发送率怎么办?

分组窗口

  • 为了解决所有这些问题,我们以假设每个分组有一个序列号开始,正如前面所描述的。 我们定义一个分组窗口作为已被发送方注入但还没完成确认(如,发送方还从没收到过它们的ACK)的分组(或者它们的序列号)的集合
  • 我们把这个窗口中的分组数量称为窗口大小
  • 术语窗口来自这样的想法:如果你把在一个通信对话中发送的所有分组排成长长的一行,但只能通过一个小孔来观察它们,你就只能看到它们的一个子集——像通过一个窗口观看一样
  • 发送方的窗口(以及其他分组队列)可下图所示

滑动窗口

  • 上图显示了当前三个分组的窗口,整个窗口大小是3(窗口大小是指已被发送方注入但还没完全确认的集合)
  • 各分组概念:
    • 3号分组已经被发送和确认,所以由发送方保存的它的副本可以被释放
    • 4~5号分组:代表已经发送但还没有确认的集合
    • 分组7在发送方已经准备好,但还没被发送,因为它还没“进入”窗口
      • 现在如果我们想象数据开始从发送方流到接收方,ACK开始以相反的方向流动,发送方可能下一步就接收到一个分组4的ACK。当这发生时,窗口向右边“滑动”一个分组,意味着分组4的副本可以释放了,而分组7可以被发送了
  • 窗口的这种滑动给这种类型的协议增加了一个名字,滑动窗口协议
  • 这种滑动窗口方法可用于对付到目前为止描述过的许多问题
  • 一般来说,这个窗口结构在发送方和接收方都会有:
    • 在发送方,它记录着哪些分组可被释放,哪些分组正在等待 ACK,以及哪些分组还不能被发送
    • 在接收方,它记录着哪些分组已经被接收和确认,哪些分组是下一步期望的(和已经分配多少内存来保存它们),以及哪些分组即使被接收也将会因内存限制而被丢弃

四、变量窗口:流量控制和拥塞控制

  • 尽管窗口结构便于记录在发送方和接收方之间流动的数据,但是关于窗口应多大,或者如果接收方或者网络处理不过来发送方的数据率时会发生什么,它都没有提供指导建议。现在我们应该看看这些怎样关联在一起

流量控制

  • 为了处理当接收方相对发送方太慢时产生的问题,我们介绍一种方法,在接收方跟不上时会强迫发送方慢下来,这称为流量控制
  • 该控制经常以下述两种方式之一来进行操作:
    • 一种方式称为基于速率流量控制,它是给发送方指定某个速率,同时确保数据永远不能超过这个速率发送。这种类型的流量控制最适合流应用程序,可被用于广播和组播发现
    • 另一种流量控制的主要形式叫基于窗口流量控制,是使用滑动窗口时最流行的方法
      • 在这种方法里,窗口大小不是固定的,而是允许随时间而变动的。
      • 为了使用这种技术进行流量控制,必须有一种方法让接收方可以通知发送方使用多大的窗口。这一般称为窗口通告,或简单地称为窗口更新。发送方(即窗口通告的接收者)使用该值调整其窗口大小
      • 逻辑上讲,一个窗口更新是与我们前面讨论过的ACK分离的,但是实际上窗口更新和ACK是由同一个分组携带的,意味着发送方往往会在它的窗口滑动到右边的同时调整它的大小
  • 流量控制的原理:
    • 如果我们考虑到在发送方修改窗口大小会带来的影响,就可以很明显地知道这是怎样达到流量控制的
    • 在没收到它们中任何一个的ACK之前,发送方允许注入W个分组到网络中。如果发送方和接收方足够快,网络中没有丢失一个分组以及有无穷的空间的话,这意味着通信速率正比于(SW/R)b/s,这里W是窗口大小,S是分组大小(按比特算),R是往返时间(RTT)。当来自接收方的窗口通告夹带着发送方的值W时,那么发送方的全部速率就被限制而不能超越接收方

拥塞控制

  • 流量控制可以很好地保护接收方,但是对于中间的网络呢?在发送方和接收方之间可能会有有限内存的路由器,它们与低速网络链路抗争着。当这种情况出现时,发送方的速率可能超过某个路由器的能力,从而导致丢包。这由一种特殊的称为拥塞控制的流量控制形式来处理
  • 拥塞控制涉及发送方减低速度以不至于压垮其与接收方之间的网络。回想我们关于流量控制的讨论,我们使用一个窗口通告来告之发送方为接收方减慢速度。这称为明确发信,因为有一个协议字段专用于通知发送方正在发生什么。另一个选项可能被发送方用于猜测它需要慢下来,这种方法涉及隐性发信一涉及根据其他某些证据来决定减慢速度
  • 数据报类型的网络或更一般的与之关联的排队理论中的拥塞控制问题仍然是这些年的一个主要研究课题,它甚至不太可能完全解决所有情况。在这里讨论关于流量控制的所有选择和方法也并不现实。有兴趣的读者可参考[J90]、[K97]和[K75]。在后面“TCP拥塞控制”文章中将更详细地探讨实际用于TCP中的拥塞控制技术,以及这些年来出现的许多变体

五、设置重传超时

  • 基于重传的可靠协议的设计者要面对的一个最重要的性能问题是,要等待多久才能判定 一个分组已丢失并将它重发。用另一种方式说,重传超时应该是多大?
  • 直观上看,发送方在重发一个分组之前应等待的时间量大概是下面时间的总和:发送分组所用的时间,接收方处理它和发送一个ACK所用的时间,ACK返回到发送方所用的时间,以及发送方处理ACK 所用的时间。不幸的是,实际上这些时间没有一个是可以确切知道的。更糟的是,它们中的某些或全部会随着来自终端主机或路由器的额外负载的增加或减少而随时改变
  • 让用户去告诉协议实现在所有情况下的每个时刻应取什么超时时间(或使它们保持最新),这是不现实的一个更好的策略是让协议实现尝试去估计它们。这称为往返时间估计,这是一个统计过程。总的来说,选择一组RTT样本的样本均值作为真实的RTT是最有可能的。注意到这个平均值很自然地会随着时间而改变(它不是静态的),因为通信穿过网络的路径可能会改变
  • 做出对RTT的一些估计之后,关于设置实际的用于触发重传的超时取值问题依然存在。 如果我们回想一下均值的定义,会知道它绝不可能是一组样本的极值(除非它们全部一样)。 所以,把重传计时器的值设置成正好等于平均估计量是不合理的,因为很有可能许多实际的 RTT将会比较大,从而会导致不必要的重传。很明显,超时应该设置成比均值要大的某个 值,但是这个值与均值的确切关系是什么(或者甚至直接就使用均值)还不清楚。超时设置得太大也是不可取的,因为这反过来会导致网络变得空闲,从而降低吞吐量。对这个话题的进一步探究会在后面“TCP超时与重传”文章中介绍

转载地址:https://dongshao.blog.csdn.net/article/details/104014872 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:TCP/IP卷一:64---TCP基础之(传输控制协议(TCP)概述、TCP的可靠性、TCP报文格式与封装)
下一篇:Linux(内核剖析):26---中断下半部之(工作队列机制(workqueue_struct、cpu_workqueue_struct))

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月15日 04时31分41秒