计算机网络(五):运输层

一、运输层协议概述

1.进程之间的通信

  从通信和信息处理的角度看,运输层向它上面的应用层提供通信服务,它属于面向通信部分的最高层,同时也是用户功能中的最低层。当网络的边缘部分中的两台主机使用网络的核心部分的功能进行端到端的通信时,只有主机的协议栈才有运输层,而网络核心部分中的路由器在转发分组时都只用到下三层的功能。

  下图中两个运输层之间有一个双向粗箭头,写明"运输层提供应用进程间的逻辑通信"。"逻辑通信"的意思是∶从应用层来看,只要把应用层报文交给下面的运输层,运输层就可以把这报文传送到对方的运输层(哪怕双方相距很远,例如几千公里),好像这种通信就是沿水平方向直接传送数据。但事实上这两个运输层之间并没有一条水平方向的物理连接。数据的传送是沿着图中的虚线方向(经过多个层次)传送的。

在这里插入图片描述

  网络层和运输层有明显的区别。网络层为主机之间提供逻辑通信,而运输层为应用进程之间提供端到端的逻辑通信。

  运输层还要对收到的报文进行差错检测。

2.运输层的两个重要协议

  TCP/IP 运输层的两个主要协议都是互联网的正式标准,即∶

  • 用户数据报协议 UDP
  • 传输控制协议 TCP

在这里插入图片描述

  在 TCP/IP体系中,则根据所使用的协议是TCP或 UDP,分别称之为 TCP 报文段或 UDP 用户数据报。

  UDP 在传送数据之前不需要先建立连接。远地主机的运输层在收到 UDP报文后,不需要给出任何确认。虽然UDP不提供可靠交付,但在某些情况下UDP却是一种最有效的工作方式。

  TCP 则提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。TCP 不提供广播或多播服务。由于 TCP 要提供可靠的、面向连接的运输服务,因此不可避免地增加了许多的开销,如确认、流量控制、计时器以及连接管理等。这不仅使协议数据单元的首部增大很多,还要占用许多的处理机资源。

3.运输层的端口

  运输层使用协议端口号,或通常简称为端口。这就是说,虽然通信的终点是应用进程,但只要把所传送的报文交到目的主机的某个合适的目的端口,剩下的工作(即最后交付目的进程)就由TCP或UDP来完成。

  请注意,这种在协议栈层间的抽象的协议端口是软件端口,和路由器或交换机上的硬件端口是完全不同的概念。硬件端口是不同硬件设备进行交互的接口,而软件端口是应用层的各种协议进程与运输实体进行层间交互的一种地址。不同的系统具体实现端口的方法可以是不同的(取决于系统使用的操作系统)。

  在后面将讲到的UDP和TCP的首部格式中,我们将会看到它们都有源端口和目的端口这两个重要字段。当运输层收到 IP 层交上来的运输层报文时,就能够根据其首部中的目的端口号把数据交付应用层的目的应用进程。TCP/IP 的运输层用一个 16 位端口号来标志一个端口。但请注意,端口号只具有本地意义,它只是为了标志本计算机应用层中的各个进程在和运输层交互时的层间接口。在互联网不同计算机中,相同的端口号是没有关联的。

  • 服务器端使用的端口号:

  这里又分为两类,最重要的一类叫做熟知端口号/系统端口号,数值为0~1023。这些数值可在网址 www.iana.org查到。 IANA 把这些端口号指派给了 TCP/IP 最重要的一些应用程序,让所有的用户都知道。当一种新的应用程序出现后,IANA 必须为它指派一个熟知端口,否则互联网上的其他应用进程就无法和它进行通信。下表给出了一些常用的熟知端口号。

在这里插入图片描述

  另一类叫做登记端口号,数值为 1024~49151。这类端口号是为没有熟知端口号的应用程序使用的。使用这类端口号必须在 IANA 按照规定的手续登记,以防止重复。

  • 客户端使用的端口号:

  数值为 49152~65535。由于这类端口号仅在客户进程运行时才动态选择,因此又叫做短暂端口号。这类端口号留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的端口号,因而可以把数据发送给客户进程。通信结束后,刚才已使用过的客户端口号就不复存在,这个端口号就可以供其他客户进程使用。

二、用户数据报协议UDP

1.概述

  用户数据报协议 UDP 只在IP 的数据报服务之上增加了很少一点的功能,这就是复用和分用的功能以及差错检测的功能。UDP 的主要特点是∶

  • UDP是无连接的。
  • 尽最大努力交付,即不保证可靠交付。
  • UDP 是面向报文的。发送方的 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。在接收方的 UDP,对IP层交上来的 UDP用户数据报,在去除首部后就原封不动地交付上层的应用进程。因此,应用程序必须选择合适大小的报文。

在这里插入图片描述

  • UDP没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。
  • UDP 支持一对一、一对多、多对一和多对多的交互通信。
  • UDP 的首部开销小,只有8 个字节。

  当很多的源主机同时都向网络发送高速率的实时视频流时,网络就有可能发生拥塞,结果大家都无法正常接收。因此,不使用拥塞控制功能的 UDP 有可能会引起网络产生严重的拥塞问题。

  还有一些使用 UDP的实时应用,需要对 UDP 的不可靠的传输进行适当的改进,以减少数据的丢失。

2.首部格式

在这里插入图片描述

  • 源端口号。在需要对方回信时选用。不需要时可用全0。
  • 目的端口号。这在终点交付报文时必须使用。
  • 长度。UDP用户数据报的长度,其最小值是8(仅有首部)。
  • 校验和。检测 UDP用户数据报在传输中是否有错,有错就丢弃。把首部和数据部分一起都检验。

  当运输层从IP 层收到 UDP数据报时,就根据首部中的目的端口,把 UDP数据报通过相应的端口,上交最后的终点——应用进程。下图是UDP基于端口分用的示意图。

在这里插入图片描述

  如果接收方 UDP 发现收到的报文中的目的端口号不正确(即不存在对应于该端口号的应用进程),就丢弃该报文,并由网际控制报文协议 ICMP 发送"端口不可达"差错报文给发送方。

三、传输控制协议TCP

1.概述

  • TCP是面向连接的运输层协议。这里的连接是指逻辑连接。
  • 每一条 TCP连接只能有两个端点每一条 TCP连接只能是点对点的。
  • TCP 提供可靠交付的服务。通过 TCP连接传送的数据,无差错、不丢失、不重复,并且按序到达。
  • TCP 提供全双工通信。TCP 允许通信双方的应用进程在任何时候都能发送数据。
  • 面向字节流。虽然应用程序和 TCP的交互是一次一个数据块(大小不等),但 TCP 把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。TCP 并不知道所传送的字节流的含义。TCP 不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系。

在这里插入图片描述

  • TCP 和 UDP在发送报文时所采用的方式完全不同。TCP 并不关心应用进程一次把多长的报文发送到 TCP 的缓存中,而是根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP发送的报文长度是应用进程给出的)。如果应用进程传送到 TCP 缓存的数据块太长,TCP 就可以把它划分短一些再传送。如果应用进程一次只发来一个字节,TCP 也可以等待积累有足够多的字节后再构成报文段发送出去。

2.TCP的连接

  前面已经讲过,每一条 TCP 连接有两个端点。TCP连接的端点叫做套接字(socket)或插口。虽然有时为了方便,我们也可以说,在一个应用进程和另一个应用进程之间建立了一条 TCP连接,但一定要记住∶TCP连接的端点是个很抽象的套接字,即(IP 地址∶端口号)。也还应记住∶同一个 IP 地址可以有多个不同的TCP 连接,而同一个端口号也可以出现在多个不同的 TCP 连接中。

3.可靠传输的工作原理

  我们知道,TCP 发送的报文段是交给 IP 层传送的。但 IP 层只能提供尽最大努力服务,也就是说,TCP 下面的网络所提供的是不可靠的传输。因此,TCP必须采用适当的措施才能使得两个运输层之间的通信变得可靠。

  理想的传输条件有以下两个特点∶

  • 传输信道不产生差错。
  • 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据。

  在这样的理想传输条件下,不需要采取任何措施就能够实现可靠传输。

(1)停止等待协议

  "停止等待"就是每发送完一个分组就停止发送,等待对方的确认,在收到确认后再发送下一个分组。

  • 无差错情况:

  下图是最简单的无差错情况。A发送分组M1,发完就暂停发送,等待 B 的确认。B 收到了 M1就向 A 发送确认。A 在收到了对 M1的确认后,就再发送下一个分组 M2。同样,在收到B 对 M2的确认后,再发送 M3。

在这里插入图片描述

  • 出现差错:

  下图是分组在传输过程中出现差错的情况。B 接收 M1时检测出了差错,就丢弃 M,其他什么也不做(不通知 A 收到有差错的分组);或者M1在传输过程中丢失了。在这两种情况下,B 都不会发送任何信息。A 只要超过了一段时间仍然没有收到确认,就认为刚才发送的分组丢失了,因而重传前面发送过的分组。这就叫做超时重传。

在这里插入图片描述

  要实现超时重传,就要在每发送完一个分组时设置一个超时计时器。如果在超时计时器到期之前收到了对方的确认,就撤销已设置的超时计时器。

  这里应注意以下三点:
  第一,A在发送完一个分组后,必须暂时保留已发送的分组的副本(在发生超时重传时使用)。只有在收到相应的确认后才能清除暂时保留的分组副本。
  第二,分组和确认分组都必须进行编号。这样才能明确是哪一个发送出去的分组收到了确认,而哪一个分组还没有收到确认。
  第三,超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。显然,如果重传时间设定得很长,那么通信的效率就会很低。但如果重传时间设定得太短,以致产生不必要的重传,就浪费了网络资源。

  • 确认丢失和确认迟到:

在这里插入图片描述

  • 信道利用率:

在这里插入图片描述

  信道利用率公式如下:

在这里插入图片描述

  停止等待协议的优点是简单,但信道利用率实在是太低了,尤其当需要重传时,效率还会更低。

  为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输。流水线传输就是发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。这样可使信道上一直有数据不间断地在传送。显然,这种传输方式可以获得很高的信道利用率。当使用流水线传输时,就要使用下一节介绍的连续 ARQ 协议。

在这里插入图片描述

(2)连续ARQ协议

  下图表示发送方维持的发送窗口,它的意义是∶位于发送窗口内的 5 个分组都可连续发送出去,而不需要等待对方的确认。这样,信道利用率就提高了。

在这里插入图片描述

  连续 ARQ 协议规定,发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。

  接收方一般都是采用累积确认的方式。这就是说,接收方不必对收到的分组逐个发送确认,而是在收到几个分组后,对按序到达的最后一个分组发送确认,这就表示∶ 到这个分组为止的所有分组都已正确收到了。

  累积确认有优点也有缺点。优点是∶容易实现,即使确认丢失也不必重传。但缺点是不能向发送方反映出接收方已经正确收到的所有分组的信息。
  例如,如果发送方发送了前 5 个分组,而中间的第 3 个分组丢失了。这时接收方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次。这就叫做 Go-back-N(回退 N),表示需要再退回来重传已发送过的 N个分组。可见当通信线路质量不好时,连续 ARQ 协议会带来负面的影响。

4.TCP报文段的首部格式

在这里插入图片描述

  • 源端口和目的端口
  • 序号: 例如,一报文段的序号字段值是 301,而携带的数据共有 100字节。这就表明∶ 本报文段的数据的第一个字节的序号是 301,最后一个字节的序号是 400。显然,下一个报文段(如果还有的话)的数据序号应当从 401 开始,即下一个报文段的序号字段值应为 401。这个字段的名称也叫做"报文段序号"。
  • 确认号: 若确认号 为N,则表明∶ 到序号 N-1为止的所有数据都已正确收到。
  • 数据偏移: 它指出 TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远。这个字段实际上是指出 TCP 报文段的首部长度。由于首部中还有长度不确定的选项字段,因此数据偏移字段是必要的。单位是32 位字,即4B。
  • 保留: 保留为今后使用,但目前应置为0。
  • 紧急 URG: 当 URG = 1时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据),而不要按原来的排队顺序来传输。
  • 确认 ACK: 仅当 ACK=1时确认号字段才有效。当 ACK= 0时,确认号无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置1。
  • 推送 PSH: 当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情况下,TCP 就可以使用推送操作,而不再等到整个缓存都填满了后再向上交付。虽然应用程序可以选择推送操作,但推送操作很少使用。
  • 复位 RST: 当RST = 1时,表明TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。RST 置 1还用来拒绝一个非法的报文段或拒绝打开一个连接。RST也可称为重建位或重置位。
  • 同步 SYN: 在连接建立时用来同步序号。当 SYN=1而 ACK= 0 时,表明这是一个连接请求报文段。对方若同意建立连接,则应在响应的报文段中使 SYN=1和 ACK=1。
  • 终止 FIN : 用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。
  • 窗口: 指的是发送本报文段的一方的接收窗口(而不是自己的发送窗口)。窗口值告诉对方∶ 从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量(以字节为单位)。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。窗口值常常在动态变化着。
  • 检验和: 检验和字段检验的范围包括首部和数据这两部分。
  • 紧急指针: 仅在 URG = 1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。因此,紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时,TCP 就告诉应用程序恢复到正常操作。值得注意的是,即使窗口为零时也可发送紧急数据。
  • 选项: 长度可变,最长可达 40 字节。当没有使用"选项"时,TCP的首部长度是20字节。

  目前,选项有:最大报文段长度MSS(规定了数据的最大长度)、窗口扩大(夸大窗口)、时间戳选项、选择确认选项。

5.TCP可靠传输的实现

(1)以字节为单位的滑动窗口

  TCP 的滑动窗口是以字节为单位的。

在这里插入图片描述

  从上图可以看出,要描述一个发送窗口的状态需要三个指针∶P1,P2和 P3。指针都指向字节的序号。这三个指针指向的几个部分的意义如下∶

  • 小于P1的是已发送并已收到确认的部分,而大于P3的是不允许发送的部分。
  • P3-P1=A的发送窗口
  • P2-P1= 已发送但尚未收到确认的字节数
  • P3-P2= 允许发送但当前尚未发送的字节数(又称为可用窗口或有效窗口)

  再看一下 B的接收窗口。B的接收窗口大小是 20。在接收窗口外面,到30号为止的数据是已经发送过确认,并且已经交付主机了。因此在 B 可以不再保留这些数据。接收窗口内的序号(31~50)是允许接收的。在上图中,B收到了序号为32和 33的数据。这些数据没有按序到达,因为序号为 31 的数据没有收到(也许丢失了,也许滞留在网络中的某处)。请注意,B 只能对按序收到的数据中的最高序号给出确认,因此 B发送的确认报文段中的确认号仍然是 31(即期望收到的序号),而不能是 32 或 33。

  现在假定 B收到了序号为 31 的数据,并把序号为31~33的数据交付主机,然后B删除这些数据。接着把接收窗口向前移动3个序号(如下图),同时给 A发送确认,其中窗口值仍为 20,但确认号是 34。这表明 B已经收到了到序号 33 为止的数据。我们注意到,B还收到了序号为 37,38 和 40 的数据,但这些都没有按序到达,只能先暂存在接收窗口中。 A 收到B 的确认后,就可以把发送窗口向前滑动3个序号,但指针P2不动。可以看出,现在 A的可用窗口增大了,可发送的序号范围是 42~53。

在这里插入图片描述

  A在继续发送完序号 42 ~53 的数据后,指针P2向前移动和P1重合。发送窗口内的序号都已用完,但还没有再收到确认(如下图)。由于A的发送窗口已满,可用窗口已减小到零,因此必须停止发送。请注意,存在下面这种可能性,就是发送窗口内所有的数据都已正确到达 B,B 也早已发出了确认。但不幸的是,所有这些确认都滞留在网络中。在没有收到 B 的确认时,A 不能猜测∶"或许 B 收到了吧!"为了保证可靠传输,A 只能认为B还没有收到这些数据。于是,A在经过一段时间后(由超时计时器控制)就重传这部分数据,重新设置超时计时器,直到收到B 的确认为止。如果 A 收到确认号落在发送窗口内,那么 A就可以使发送窗口继续向前滑动,并发送新的数据。

在这里插入图片描述

(2)超时重传时间的选择

  上面已经讲到,TCP 的发送方在规定的时间内没有收到确认就要重传已发送的报文段。这种重传的概念是很简单的,但重传时间的选择却是 TCP最复杂的问题之一。

  TCP 采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的往返时间 RTT。TCP 保留了 RTT 的一个加权平均往返时间 RTTs,具体怎么计算这里略过。

(3)选择确认SACK

  现在还有一个问题没有讨论。这就是若收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么能否设法只传送缺少的数据而不重传已经正确到达接收方的数据? 答案是可以的。给TCP报文段首部添加“选择确认”选项就是一种可行的处理方法。但是,由于SACK 文档并没有指明发送方应当怎样响应 SACK。因此大多数的实现还是重传所有未被确认的数据块。

6.TCP的流量控制

(1)利用滑动窗口实现流量控制

  所谓流量控制就是让发送方的发送速率不要太快,要让接收方来得及接收。因此,发送方的发送窗口不能超过接收方给出的接收窗口的数值。

(2)TCP的传输效率

  当线路带宽并不富裕时,一般的传送方法的效率的确不高。因此应适当推迟发回确认报文,并尽量使用捎带确认的方法,可提高传输效率。

  在 TCP 的实现中广泛使用 Nagle 算法。算法如下∶若发送应用进程把要发送的数据逐个字节地送到 TCP 的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时,用这样的方法可明显地减少所用的网络带宽。Nagle 算法还规定,当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。这样做,就可以有效地提高网络的吞吐量。

  另一个问题叫做糊涂窗口综合征,有时也会使 TCP 的性能变坏。设想一种情况∶ TCP 接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1 个字节(这样就使接收缓存空间仅腾出1个字节),然后向发送方发送确认,并把窗口设置为1个字节(但发送的数据报是 40 字节长)。接着,发送方又发来1个字节的数据(请注意,发送方发送的 IP 数据报是 41 字节长)。接收方发回确认,仍然将窗口设置为 1个字节。这样进行下去,使网络的效率很低。

  要解决这个问题,可以让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。此外,发送方也不要发送太小的报文段,而是把数据积累成足够大的报文段,或达到接收方缓存的空间的一半大小。

  上述两种方法可配合使用。使得在发送方不发送很小的报文段的同时,接收方也不要在缓存刚刚有了一点小的空间就急忙把这个很小的窗口大小信息通知给发送方。

7.TCP的拥塞控制

(1)一般原理

  在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏,这种情况就叫做拥塞。所谓拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载。拥塞控制是一个全局性的过程,涉及到所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。

  由于计算机网络是一个很复杂的系统,因此可以从控制理论的角度来看拥塞控制这个问题。这样,从大的方面看,可以分为开环控制和闭环控制两种方法。开环控制就是在设计网络时事先将有关发生拥塞的因素考虑周到,力求网络在工作时不产生拥塞。但一旦整个系统运行起来,就不再中途进行改正了。

  闭环控制是基于反馈环路的概念,主要有以下几种措施∶

  • 监测网络系统以便检测到拥塞在何时、何处发生。
  • 把拥塞发生的信息传送到可采取行动的地方。
  • 调整网络系统的运行以解决出现的问题。

  有很多的方法可用来监测网络的拥塞。主要的一些指标是∶由于缺少缓存空间而被丢弃的分组的百分数、平均队列长度、超时重传的分组数、平均分组时延、分组时延的标准差,等等。上述这些指标的上升都标志着拥塞的增长。

  另一种方法是在路由器转发的分组中保留一个比特或字段,用该比特或字段的值表示网络没有拥塞或产生了拥塞。也可以由一些主机或路由器周期性地发出探测分组,以询问拥塞是否发生。

  此外,过于频繁地采取行动以缓和网络的拥塞,会使系统产生不稳定的振荡。但过于迟缓地采取行动又不具有任何实用价值。因此,要采用某种折中的方法。但选择正确的时间常数是相当困难的。

(2)拥塞控制方法

  下面讨论的拥塞控制也叫做基于窗口的拥塞控制。为此,发送方维持一个叫做拥塞窗口 cwnd(congestion window)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送方让自己的发送窗口等于拥塞窗口。

  发送方控制拥塞窗口的原则是∶ 只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,这样就可以提高网络的利用率。但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,以便缓解网络出现的拥塞。判断网络拥塞的依据就是出现了超时。

  • 慢开始:

  慢开始算法的思路是这样的∶ 当主机开始发送数据时,由小到大逐渐增大发送窗口。具体规定如下:

若 SMSS(最大报文段) >2190 字节,则设置初始拥塞窗口 cwnd=2×SMSS字节,且不得超过2个报文段。
若(SMSS>1095字节)且(SMSS≤2190 字节),则设置初始拥塞窗口cwnd=3×SMSS字节,且不得超过3个报文段。
若 SMSS ≤1095 字节,则设置初始拥塞窗口cwnd=4×SMSS字节,且不得超过4个报文段。

  可见这个规定就是限制初始拥塞窗口的字节数。慢开始规定,在每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个 SMSS 的数值。更具体些,就是:拥塞窗口 cwnd每次的增加量 =min (N,SMSS)。其中 N 是原先未被确认的、但现在被刚收到的确认报文段所确认的字节数。

  不难看出,当N< SMSS 时,拥塞窗口每次的增加量要小于 SMSS。用这样的方法逐步增大发送方的拥塞窗口cwnd,可以使分组注入到网络的速率更加合理。

  下面用例子说明慢开始算法的原理。请注意,虽然实际上 TCP 是用字节数作为窗口大小的单位。但为叙述方便起见,我们用报文段的个数作为窗口大小的单位。

  在一开始发送方先设置 cwnd=1,发送第一个报文段 M1,接收方收到后确认 M1。发送方收到对 M1的确认后,把 cwnd 从1增大到 2,于是发送方接着发送 M2和 M3两个报文段。接收方收到后发回对 M2 和 M3的确认。发送方每收到一个对新报文段的确认(重传的不算在内)就使发送方的拥塞窗口加 1,因此发送方在收到两个确认后,cwnd 就从 2 增大到4,并可发送 M4~M7,共 4个报文段。因此使用慢开始算法后,每经过一个传输轮次,拥塞窗口 cwnd 就加倍。

在这里插入图片描述

  为了防止拥塞窗口 cwnd 增长过大引起网络拥塞,还需要设置一个慢开始门限 ssthresh状态变量。慢开始门限 ssthresh 的用法如下∶

当 cwnd< ssthresh 时,使用上述的慢开始算法。
当 cwnd>ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
当 cwnd=ssthresh 时,既可使用慢开始算法,也可使用拥塞避免算法。

  • 拥塞避免:

  拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢地增大,即每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd加 1,而不是像慢开始阶段那样加倍增长。这表明在拥塞避免阶段,拥塞窗口cwnd按线性规律缓慢增长,比慢开始算法的拥塞窗口增长速率缓慢得多。但请注意,"拥塞避免"并非完全能够避免了拥塞。 "拥塞避免"是说把拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。

  • 快重传:

  采用快重传算法可以让发送方尽早知道发生了个别报文段的丢失。快重传算法首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。当发送方接受到了非连续的确认序号,就知道接收方确实没有收到该报文段,因而应当立即进行重传(即"快重传"),这样就不会出现超时,发送方也不就会误认为出现了网络拥塞。使用快重传可以使整个网络的吞吐量提高约20%。

(3)主动队列管理AQM

  所谓"主动"就是不要等到路由器的队列长度已经达到最大值时才不得不丢弃后面到达的分组,这样就太被动了。应当在队列长度达到某个值得警惕的数值时(即当网络拥塞有了某些拥塞征兆时),就主动丢弃到达的分组。这样就提醒了发送方放慢发送的速率,因而有可能使网络拥塞的程度减轻,甚至不出现网络拥塞。AQM 可以有不同实现方法,其中曾流行多年的就是随机早期检测RED(Random Early Detection)。

8.TCP的运输连接管理

(1)建立连接:三报文握手

在这里插入图片描述

  一开始,B 的 TCP 服务器进程先创建传输控制块 TCB,准备接受客户进程的连接请求。然后服务器进程就处于 LISTEN(收听)状态,等待客户的连接请求。如有,即作出响应。

  A 的 TCP 客户进程也是首先创建传输控制模块 TCB。然后,在打算建立 TCP连接时,向 B 发出连接请求报文段,这时首部中的同步位 SYN = 1,同时选择一个初始序号 seq = x。TCP规定,SYN 报文段(即 SYN=1的报文段)不能携带数据,但要消耗掉一个序号。这时,TCP 客户进程进入 SYN-SENT(同步已发送)状态。

  B 收到连接请求报文段后,如同意建立连接,则向 A 发送确认。在确认报文段中应把 SYN 位和 ACK 位都置1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。这时 TCP 服务器进程进入 SYN-RCVD(同步收到)状态。

  TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的 ACK 置 1,确认号 ack=y+1,而自己的序号seq=x+1。TCP的标准规定,ACK报文段可以携带数据。但如果不携带数据则不消耗序号,在这种情况下,下一个数据报文段的序号仍是seq=x+1。这时,TCP 连接已经建立,A 进入 ESTABLISHED(已建立连接)状态。当B 收到A 的确认后,也进入 ESTABLISHED状态。

  上面给出的连接建立过程叫做三报文握手。请注意,在上图中B 发送给 A 的报文段,也可拆成两个报文段。可以先发送一个确认报文段(ACK =1,ack=x+1),然后再发送一个同步报文段(SYN =1,seq=y)。这样的过程就变成了四报文握手,但效果是一样的。

(2)释放连接:四报文握手

在这里插入图片描述

  数据传输结束后,通信的双方都可释放连接。现在 A和 B 都处于 ESTABLISHED 状态。A 的应用进程先向其 TCP发出连接释放报文段,并停止再发送数据,主动关闭 TCP连接。A 把连接释放报文段首部的终止控制位 FN 置1,其序号 seq =u,它等于前面已传送过的数据的最后一个字节的序号加 1。这时 A 进入 FIN-WAIT-1(终止等待 1)状态,等待 B 的确认。请注意,TCP 规定,FIN 报文段即使不携带数据,它也消耗掉一个序号。

  B 收到连接释放报文段后即发出确认,确认号是 ack=u+1,而这个报文段自己的序号是 v,等于 B 前面已传送过的数据的最后一个字节的序号加 1。然后 B 就进入 CLOSE- WAIT(关闭等待)状态。TCP 服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时的 TCP 连接处于半关闭(half-close)状态,即 A 已经没有数据要发送了,但 B 若发送数据,A 仍要接收。也就是说,从B 到A 这个方向的连接并未关闭,这个状态可能会持续一段时间。

  A 收到来自 B 的确认后,就进入 FIN-WAIT-2(终止等待 2)状态,等待B发出的连接释放报文段。若B已经没有要向 A发送的数据,其应用进程就通知 TCP 释放连接。这时 B 发出的连接释放报文段必须使FIN = 1。现假定 B的序号为w(在半关闭状态B可能又发送了一些数据)。B还必须重复上次已发送过的确认号ack=u+1。这时B就进入LAST-ACK(最后确认)状态,等待 A的确认。

  A 在收到B 的连接释放报文段后,必须对此发出确认。在确认报文段中把 ACK 置 1,确认号ack=w+1,而自己的序号是seq=u+1(根据TCP标准,前面发送过的FN报文段要消耗一个序号)。然后进入到 TIME-WAIT(时间等待)状态。请注意,现在 TCP 连接还没有释放掉。必须经过时间等待计时器设置的时间 2MSL 后,A 才进入到 CLOSED状态。时间 MSL叫做最长报文段寿命(Maximum Segment Lifetime),RFC793建议设为2分钟,但TCP 允许不同的实现可根据具体情况使用更小的 MSL 值。因此,从 A进入到 TIME-WAIT 状态后,要经过 4分钟才能进入到 CLOSED 状态,才能开始建立下一个新的连接。当 A撤销相应的传输控制块 TCB 后,就结束了这次的 TCP 连接。

(3)TCP的有限状态机

  图中,粗实线箭头表示对客户进程的正常变迁,粗虚线箭头表示对服务器进程的正常变迁,另一种细线箭头表示异常变迁。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Tracycoder/article/details/113323700