下面我们来到了第三章运输层,它是位于应用层和网络层之间的,是分层网络体系结构的重要部分。
该层为运行在不同主机上的应用进程提供直接的通信服务起着至关重要的作用。
我们将特别关注因特网协议,即TCP和UDP运输协议。
一、概述和运输层服务
运输层协议为运行在不同主机上的应用进程之间提供了逻辑通信(logic communica tion) 功能。从应用程序的角度看,通过逻辑通信,运行不同进程的主机好像直接相连一 样;实际上,这些主机也许位于地球的两侧,通过很多路由器及多种不同类型的链路相连。应用进程使用运输层提供的逻辑通信功能彼此发送报文,而无须考虑承载这些报文的物理基础设施的细节。
运输层协议是在端系统中而不是在路由器中实现的。在发送端,运输层将从发送应用程序进程接收到的报文转换成运输层分组,用因特网术语来讲该分组称为 运输层报文段(segment) 。 实现的方法(可能)是将应用报文划分为较小的块,并为每块加上一个运输层首部以生成运输层报文段。然后,在发送端系统中,运输层将这些报文段传递给网络层,网路层将其封装成网络层分组(即数据报)并向目的地发送。
注意到下列事实是重要的:网络路由器仅作用于该数据报的网络层字段;即它们不检查封装在该数据报的运输层报文段的字段。在接收端,网络层从数据报中提取运输层报文段,并将该报文段向上交给运输层。运输层则处理接收到的报文段,使该报文段中的数据为接收应用进程使用。
网络应用程序可以使用多种的运输层协议。例如,因特网有两种协议,即TCP和UDP。每种协议都能为调用的应用程序提供一组不同的运输层服务。
运输层和网络层的关系
在协议栈中,运输层刚好位于网络层之上。网络层提供了主机之间的逻辑通信,而运输层为运行在不同主机上的进程之间提供了逻辑通信。
考虑有两个家庭,一家位于美国东海岸,一家位于美国西海岸,每家有12个孩子。 东海岸家庭的孩子们是西海岸家庭孩子们的堂兄弟姐妹。这两个家庭的孩子们喜欢彼此通信,每个人每星期要互相写一封信,每封信都用单独的信封通过传统的邮政服务传送。因此,每个家庭每星期向另一家发送144封信。(如果他们有电子邮件的话,这些孩子可以省不少钱!)每一个家庭有个孩子负责收发邮件,西海岸家庭是Ann而东海岸家庭是Bill。 每星期Ann去她的所有兄弟姐妹那里收集信件,并将这些信件交到每天到家门口来的邮政 服务的邮车上。当信件到达西海岸家庭时,Ann也负责将信件分发到她的兄弟姐妹手上。 在东海岸家庭中的Bill也负责类似的工作。
在这个例子中,邮政服务为两个家庭间提供逻辑通信,邮政服务将信件从一家送往另 一家,而不是从一个人送往另一个人。在另一方面,Ann和Bill为堂兄弟姐妹之间提供了 逻辑通信,Arm和Bill从兄弟姐妹那里收取信件或到兄弟姐妹那里交付信件。注意到从堂兄弟姐妹们的角度来看,Ann和Bill就是邮件服务,尽管他们只是端到端交付过程的一部 分 (即端系统部分)。在解释运输层和网络层之间的关系时,这个家庭的例子是一个非常好的类比。
值得注意的是,Ann和Bill都是在各自家里进行工作的;例如,他们并没有参与任何一个中间邮件中心对邮件进行分拣,或者将邮件从一个邮件中心送到另一个邮件中心之类的工作。类似地,运输层协议只工作在端系统中。在端系统中, 运输层协议将来自应用进程的报文移动到网络边缘(即网络层),反过来也是一样,但对有关这些报文在网络核心如何移动并不作任何规定。事实上,中间路由器既不处理也不识别运输层加在应用层报文的任何信息。
我们还是继续讨论这两家的情况。现在假定Ann和Bill外出度假,另外一对堂兄妹(如Susan和Harvey)接替他们的工作,在家庭内部进行信件的收集和交付工作。不幸的 是,Susan和Harvey的收集和交付工作与Ann和Bill所做的并不完全一样。由于年龄更小,Susan和Harvey收发邮件的次数更少,而且偶尔还会丢失邮件(有时是被家里的狗咬坏了)。因此,Susan和Harvey这对堂兄妹并没有提供与Ann和Bill—样的服务集合(即相同的服务模型)。与此类似,计算机网络中可以安排多种运输层协议,每种协议为应用程序提供不同的服务模型。
Ann和Bill所能提供的服务明显受制于邮政服务所能提供的服务。例如,如果邮政服务不能提供在两家之间传递邮件所需时间的最长期限(例如3天),那么Ann和Bill就不 可能保证邮件在堂兄弟姐妹之间传递信件的最长期限。与此类似,运输协议能够提供的服务常常受制于底层网络层协议的服务模型。如果网络层协议无法为主机之间发送的运输层 报文段提供时延或带宽保证的话,运输层协议也就无法为进程之间发送的应用程序报文提供时延或带宽保证。
然而,即使底层网络协议不能在网络层提供相应的服务,运输层协议也能提供某些服务。即使底层网络协议是不可靠的,也就是说网络层协议会使分组丢失、篡改和冗余,运输协议也能为应用程序提供可靠的数据传输服务。另一个例子是,即使网络层不能保证运输层报文段的机密性,运输协议也能使用加密来确保应用程序报文不被入侵者读取。
运输层概述
前面讲过因特网为应用层提供了两种截然不同的可用运输层协议。这些协议一种是UDP (用户数据报协议),它为调用它的应用程序提供了一种不可靠、无连接的服务。另一种是TCP (传输控制协议),它为调用它的应用程序提供了一种可靠的、面向连接的服 务。
UDP和TCP最基本的责任是,将两个端系统间IP的交付服务扩展为运行在端系统上的两个进程之间的交付服务。
UDP:不可靠的服务。
TCP:可靠的数据传输、拥塞控制。
二、多路复用与多路分解
还是上面的例子:当Bill从邮件员手里接收到多个信件,把它们分配给他的堂表兄弟姐妹,这个过程就是多路分解。当Ann从兄弟姐妹那里收集来信件,交给邮件员,这个过程就是多路复用。
将运输层报文段中的数据交付到正确的套接字的工作称为多路分解(demultiplexing)。在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息(这将在以后用于分解)从而生成报文段,然后将报文段传递到网络层,所有这些工作称为多路复用(nmhiplexing)。
多路复用的要求:①套接字有唯一的标识符;②每个报文段有特殊字段来指示该报文段交付到的套接字。
在主机上的每个套接字能够分配一个端口号,当报文段到达主机时,运输层检查报文段中的端口号,并将其定向到响应的套接字。然后报文段中的数据通过套接字进入其所连接的进程。
无连接的多路复用与多路分解
一个UDP套接字是由一个二元组全面标识的:目的IP地址、目的端口号。
即,如果有两个UDP报文段有不同的源IP地址、源端口号(即从不同地点发送),但具有相同的目的IP地址、目的端口号(相同的接收点),那么这两个报文段将通过相同的目的套接字被定向到相同的目的进程。
面向连接的多路复用与多路分解
一个TCP套接字是由一个四元组全面标识的:源IP地址、源端口号、目的IP地址、目的端口号。
服务器主机可以支持很多并行的TCP套接字,每个套接字与一个进程相联系,并由其四元组来标识每个套接字。当一个TCP报文段到达主机时,所有4个字段(源IP地址、源端口号、目的IP地址、目的端口号)被用来将报文段定向(分解)到响应的套接字。
Web服务器与TCP
考虑一台运行Web服务器的主机,例如在端口 80上运行一个Apache Web服务器。当客户(如浏览器)向该服务器发送报文段时,所有报文段的目的端口都将为80。特别是,初始连接建立报文段和承载HTTP请求的报文段都有80的目的端口。如我们刚才描述的那样,该服务器能够根据源IP地址和源端口号来区分来自不同客户的报文段。
每个这样的进程都有自己的连接套接字,通过这些套接字可以收到HTTP请求和发送HTTP响应。然而,我们要提及的是,连接套接字与进程之间并非总是有着一一对应的关系。事实上,当今的高性能Web服务器通常只使用一个进程,但是为每个新的客户连接创建一个具有新连接套接字的新线程。(线程可被看作是一个轻量级的子进程。)
如果客户与服务器使用持续HTTP,则在整条连接持续期间,客户与服务器之间经由同一个服务器套接字交换HTTP报文。然而,如果客户与服务器使用非持续HTTP,则对每一对请求/响应都创建一个新的TCP连接并在随后关闭,因此对每一对请求/响应创建一个新的套接字并在随后关闭。这种套接字的频繁创建和关闭会严重地影响一个繁忙的Web 服务器的性能(尽管有许多操作系统技巧可用来减轻这个问题的影响)。
三、无连接运输:UDP
-
UDP只是做了运输协议能做的最少工作。除了复用/分解功能及少量的差错检测外,它几乎没有对IP增加别的东西。
-
发送方和接收方的运输层实体之间没有握手,正因为如此,UDP被称为是无连接的。
-
DNS是一个通常使用UDP的应用层协议的例子。
实时应用通常要求最小的发送速率,不希望过分的延迟报文段的发送,且能容忍一些数据丢失,TCP服务模型不是特别适合这些应用的需要,可以是使用UDP。
- 无须连接建立。
- 无连接状态。
- 分组首部开销小。
UDP报文段结构
UDP首部只有4 个字段,每个字段由两个字节组成。通过端口号可以使目的主机将应用数据交给运行在目的端系统中的相应进程(即执行分解功能)。长度字段指示了在UDP报文段中的字节数(首部加数据)。接收方使用检验和来检查在该报文段中是源端口号长度目的端口号 检验和应用数据(报文)UDP报文段结构否出现了差错。
UDP检验和
UDP检验和提供了差错检验功能(通过反码运算),虽然UDP提供差错检验,但它对差错恢复无能为力。
UDP的某种实现只是丢弃受损的报文段,其他实现是将受损的报文段交给应用程序并给出警报。
四、可靠数据传输原理
数据可以通过一条可靠的信道进行传输。借助于可靠信道,传输数据比特就不会受到损坏 (由0变为1,或者相反)或丢失,而且所有数据都是按照其发送顺序进行交付。这恰好就是TCP向调用它的因特网应用所提供的服务模型。
实现这种服务抽象是可靠数据传输协议(reliable data transfer protocol)的责任。由于可靠数据传输协议的下层协议也许是不可靠的,因此这是一项困难的任务。例如,TCP是在不可靠的(IP)端到端网络层之上实现的可靠数据传输协议。
更一般的情况是,两个可靠通信端点的下层可能是由一条物理链路(如在链路级数据传输协议的场合下)组成或是由一个全球互联网络(如在运输级协议的场合下)组成。然而,就我们的目的而言,我们可将较低层直接视为不可靠的点对点信道。
构造可靠数据传输协议
一步步深入后得到一个完美、可靠的数据传输协议:
1. 经完全可信通道的可靠数据传输:rdt1.0
下图这样的表示称为有限状态机(Finite-State Machine,FSM)
在这个简单的协议中,一个单元数据与一个分组没差别。而且,所有分组是从发送方流向接收方;有了完全可靠的信道,接收端就不需要提供任何反馈信息给发送方,因为不必担心出现差错!注意到我们也已经假定了接收方接收数据的速率能够与发送方发送数据的速率一样快。因此,接收方没有必要请求发送方慢一点!
2.经够比特差错信道的可靠数据传输:rdt2.x
在通常情况下,报文接收者在听到、理解并记下每句话后可能会说“0K”。如果报文接收者听到一句含糊不清的话时, 他可能要求你重复那句容易误解的话。这种口述报文协议使用了肯定确认(positive ac knowledgment)("OK”)与否定确认(negativeacknowledgmenl)("请重复一遍)。这些控制报文使得接收方可以让发送方知道哪些内容被正确接收,哪些内容接收有误并因此需要重复。在计算机网络环境中,基于这样重传机制的可靠数据传输协议称为自动重传请求(Automatic Repeat reQuest, ARQ)协议。
ARQ需要另外三种协议功能来处理存在比特差错的情况:差错检验、接收方反馈、重传。
- rdt2.0:该数据传输协议采用了差错检验、肯定确认与否定确认。
当发送方处于等待ACK或NAK的状态时,它不能从上层获得更多的数据;这就是说,rdcsend()事件不可能岀现;仅当接收到ACK并离开该状态时才能发生这样的事件。因此,发送方将不会发送 一块新数据,除非发送方确信接收方已正确接收当前分组。由于这种行为,rdt2.0这样的协议被称为停等(stop-and-wait)协议。
但是ACK或NAK分组有受损的可能性!
解决这个新问题的一个简单方法(几乎所有现有的数据传输协议中,包括TCP,都采用了这种方法)是在数据分组中添加一新字段,让发送方对其数据分组编号,即将发送数据分组的序号(sequence number)放在该字段。于是,接收方只需要检查序号即可确定收到的分组是否一次重传。
- rdt2.1:协议rdt2.1使用了从接收方到发送方的肯定确认和否定确认。当接收到失序的分组 时,接收方对所接收的分组发送一个肯定确认。如果收到受损的分组,则接收方将发送一 个否定确认。如果不发送NAK,而是对上次正确接收的分组发送一个ACK,我们也能实现与NAK—样的效果。
- rdt2.2:发送方接收到对同一个分组的两个ACK(即接收冗余ACK(duplicate ACK))后,就知道接收方没有正确接收到跟在被确认两次的分组后面的分组。 rdt2.2是在有比特差错信道上实现的一个无NAK的可靠数据传输协议。rdt2. 1和rdt2.2之间的细微变化在于,接收方此时必须包括由一个ACK报 文所确认的分组序号(这可以通过在接收方FSM中,在make.pkt()中包括参数ACK 0或 ACK1来实现),发送方此时必须检查接收到的ACK报文中被确认的分组序号(这可通过 在发送方FSM中,在isACK()中包括参数0或1来实现)。
3.经具有比特差错的丢包信道的可靠数据传输:rdt3.0
解决丢包问题:让发送方负责检测和恢复丢包工作,从发送方角度,重传是一种万能灵药,需要一个倒计数定时器。
有丢包和延迟分组情况协议运作情况:
现在我们归纳一下数据传输协议的要点:在检验和、序号、定时器、肯定和否定确定这些技术中,每种机制都在协议的运行中起到了必不可少的作用。至此,我们得到了一个可靠数据传输协议。
流水线可靠数据传输协议
- rdt3.0性能问题的核心在于它是一个停等协议。
- 许多从发送方向接收方输送的分组可以被看成是填充到一条流水线中,故这种技术被称为流水线(pipelining)。
流水线技术对可靠数据传输协议可带来如下影响:
- 必须增加序号范围,因为每个输送中的分组(不计算重传的)必须有一个唯一的序号,而且也许有多个在传输中的未确认的报文。
- 协议的发送方和接收方两端也许不得不缓存多个分组。发送方最低限度应当能缓冲那些已发送但没有确认的分组。接收方或许也需要缓存那些已正确接收的分组。
- 所需序号范围和对缓冲的要求取决于数据传输协议如何处理丢失、损坏及延时过大的分组。解决流水线的差错恢复有两种基本方法:回退N步(Go-Back-N,GBN)和选择重传(Selective Repeat,SR)。
回退N步
GBN会丢所有失序分组,尽管丢弃一个正确接收(但失序)的分组有点蠢。
选择重传
- 可靠数据传输机制和用途总结:
五、面向连接的运输:TCP
TCP是因特网运输层面向连接的可靠运输协议。
TCP连接
TCP被称为是面向连接的(connection-oriented),这是因为在一个应用进程可以开始向另一个应用进程发送数据之前,这两个进程必须先相互“握手”,即它们必须相互发送某些预备报文段,以建立确保数据传输的参数。
这种TCP “连接”不是一条像在电路交换网络中的端到端TDM或FDM电路。相反,该 “连接”是一条逻辑连接,其共同状态仅保留在两个通信端系统的TCP程序中。
前面讲过,由于TCP协议只在端系统中运行,而不在中间的网络元素(路由器和链路层交换机)中运行,所以中间的网络元素不会维持TCP连接状态。事实上,中间路由器对TCP连接完全视而不见,它们看到的是数据报,而不是连接。
TCP连接也总是点对点(point-to-point)的,即在单个发送方与单个接收方之间的连接。
大致连接过程:
- 客户首先发送一个特殊的TCP报文段
- 服务器用另一个特殊的TCP报文段来响应
- 最后,客户再用第三个特殊报文段作为相应
前两个报文段不承载“有效载荷”,也就是不包含应用层数据;而第三个报文段可以承载有效载荷。
由于在这两台主机之间发送了3个报文段,所以这种连接建立过程常被称为三次握手(three-way handshake)
TCP连接的组成包括:一台主机上的缓存、变量(目的端口、源端口号)和与进程连接的套接字,以及另一台主机上的另一组缓存、变量和与进程连接的套接字。如前面讲过的那样,在这两台主机之间的网络元素(路由器.交换机和中继器)中,没有为该连 接分配任何缓存和变量。
TCP将这些数据引导到该连接的发送缓存(sendbuffej里,发送缓存是发起三次 握手期间设置的缓存之一。接下来TCP就会不时从发送缓存里取出一块数据,并将数据传递到网络层。
TCP可从缓存中取出并放入报文段中的数据数量受限于最大报文段长度(Maximum Segment Size, MSS)。MSS通常根据最初确定的由本地发送主机发送的最大链路层帧长度(即所谓的最大传输单元(Maximum Transmission Unit, MTU))来设置。
TCP报文段结构
与UDP —样,首部包括源端口号和目的端口号,它被用于多路复用/分解来自或送到上层应用的数据。另外,同 UDP—样,TCP首部也包括检验和字段(checksum field) 。
TCP报文段首部还包含下列字段:
- 32比特的序号字段(sequence number field)和32比特的确认号字段(acknowledgment number field)。这些字段被TCP发送方和接收方用来实现可靠数据传输服务。
- 16比特的接收窗口字段(receivewindowfield),该字段用于流量控制。我们很快就会看到,该字段用于指示接收方愿意接受的字节数量。
- 4比特的首部长度字段(headerlengthfield),该字段指示了以32比特的字为单位的TCP首部长度。由于TCP选项字段的原因,TCP首部的长度是可变的。(通常,选项字段为空,所以TCP首部的典型长度是20字节。)
- 可选与变长的选项字段(options field),该字段用于发送方与接收方协商最大报文段长度(MSS)时,或在高速网络环境下用作窗口调节因子时使用。首部字段中还定义了一个时间戳选项。
- 6比特的标志字段(flag field)。ACK比特用于指示确认字段中的值是有效的,即该报文段包括一个对已被成功接收报文段的确认。RST、SYN和FIN比特用于连接、建立和拆除。在明确拥塞通告中使用了CWR和、ECE比特。当PSH比特被置位时,就指示接收方应立即将数据交给上层。最后,URG比特用来指示报文段里存在着被发送端的上层实体置为“紧急”的数据。紧急数据的最后一个字节由16比特的紧急数据指针字段(urgent data pointer field)指出。当紧急数据存在并给出指向紧急数据尾指针的时候,TCP必须通知接收端的上层实体。(在实践中,PSH、URG和紧急数据指针并没有使用。为了完整性起见,才提到这些字段。)
序号和确认号:
序号:是该报文段首字节的字节流编号。假定数据流由一个包含500 000字节的文件组成,其MSS为1000字节,数据流的首字节编号是0。该TCP将为该数据流构建500个报文段。给第一个报文段分配序号0,第二个报文段分配序号1000,第三个报文段分配序号2000,以此类推。每一个序号被填入到相应TCP报文段首部的序号字段中。
确认号:主机A填充进报文段的确认号是主机A期望从主机B接收到的下一个字节的序号。
往返时间的估计与超时
Timeoutinterval = EstinMrtedRTT(RTT均值) + 4 • DevRTT(RTT偏差)
有些版本的TCP还有一个隐式NAK机制(在TCP的快速重传 机制下,收到对一个特定报文段的3个冗余ACK就可作为对后面报文段的一个隐式NAK,从而在超时之前触发对该报文段的重传)。
可靠数据传输
- 推荐的定时器管理过程仅使用单一的重传定时器,即使有多个已发送但还未被确认的报文段。
- 超时间隔加倍,这种修改提供了一个形式受限的拥塞控制。
- 快速重传,即发送冗余ACK。
- TCP的差错恢复机制也许最好被分类为GBN和SR协议的混合体。
流量控制
控制接收方的接收缓存中空闲的空间,即应用程序从接受缓存中取出的速度与IP数据传入接受缓存的速度的控制。
TCP连接管理
- 建立TCP:三次握手。
第一步:客户端的TCP首先向服务器端的TCP发送一个特殊的TCP报文段。该报 文段中不包含应用层数据。但是在报文段的首部中的一个标志位(即SYN比特)被置为1。因此,这个特殊报文段被称为SYN报文段。另外,客户会随机地选择一个初始序号(client_isn),并将此编号放置于该起始的TCP SYN报文段的序号字段中。该报文段会被封装在一个IP数据报中,并发送给服务器。 为了避免某些安全性攻击,在适当地随机化选择client_isn方面有着不少有趣的研究。
第二步:一旦包含TCP SYN报文段的IP数据报到达服务器主机(假定它的确到达,服务器会从该数据报中提取出TCP SYN报文段,为该TCP连接分配TCP缓存和变量,并向该客户TCP发送允许连接的报文段。这个允许连接的报文段也不包含应用层数据。但是,在报文段的首部却包含3个重要的信息。首先,SYN比特被置为1。其次,该TCP报文段首部的确认号字段被置为client_isn + 1。最后,服务器选择自己的初始序号(server_isn)并将其放置到TCP报文段首部的序号字段中。这个允许连接的报文段实际上表明了:“我收到了你发起建立连接的SYN分组,该分组带有初始序号 client_isn。我同意建立该连接。我自己的初始序号是server_isn。 该允许连接的报文段被称为SYNACK报文段(SYNACK segment)。
第三步:在收到SYNACK报文段后,客户也要给该连接分配缓存和变量。客户主机则向服务器发送另外一个报文段;这最后一个报文段对服务器的允许连接的报文段进行了确认(该客户通过将值server_isn + 1放置到TCP报文段首部的确认字段中来完成此项工作)。因为连接已经建立了,所以该SYN比特被置为0。该三次握手的第三个阶段可以在报文段负载中携带客户到服务器的数据。
- 拆除TCP:
客户端:
服务器端:
六、拥塞控制原理
我们已经分析了面临分组丢失时用于提供可靠数据传输服务的基本原理及特定的TCP机制。在实践中,这种丢包一般是当网络变得拥塞时由于路由器缓存溢岀引起的。分组重传因此作为网络拥塞的征兆(某个特定的运输层报文段的丢失)来对待,但是却无法处理导致网络拥塞的原因,因为有太多的源想以过高的速率发送数据。为了处理网络拥塞原因,需要一些机制以在面临网络拥塞时遏制发送方。
拥塞原因与代价
- 当分组的到达速率接近链路容量时,分组经历巨大的排队时延。
- 发送方必须执行重传以补偿因为缓存溢出而丢失(丢弃)的分组。
- 发送方在遇到较大时延时所进行的不必要重传会引起路由器利用其链路宽带来转发不必要的分组副本。
- 当一个分组沿一条路径被丢弃时,每个上游路由器用于转发该分组到丢弃该分组而使用的传输容量最终被浪费。
拥塞控制方法
- 端到端拥塞控制:TCP报文段的丢失(通过超时或3 次冗余确认而得知)被认为是网络拥塞的一个迹象,TCP 会相应地减小其窗口长度。我们还将看到关于TCP拥塞控制的一些最新建议,即使用增加的往返时延值作为网络拥塞程度增加的指示。
- 网络辅助的拥塞控制:在网络辅助的拥塞控制中,路由器向发送方提供关于网络中拥塞状态的显式反馈信息。这种反馈可以简单地用一个比特来指示链路中的拥塞情况。
- 采用阻塞分组的形式通知发送方。
- 路由器标记或更新从发送方流向接收方的分组中的某个字段来指示拥塞的产生。
七、TCP拥塞控制
因为IP层不向端系统提供显示的网络拥塞反馈,所以TCP必须使用端到端拥塞控制而不是使用网络辅助的拥塞控制。
-
三个问题:
- 一个TCP发送方如何限制它向其他发送流量的速率呢?
- 一个TCP发送方如何感知从它到目的地之间的路径上存在拥塞呢?
- 当发送方感知到端到端的拥塞时,采用何种算法改变其发送速率呢?
-
一个丢失的报文段表示着拥塞,因此当丢失报文段时应当降低TCP发送方的速率。
-
一个确认报文段指示该网络正在向接收方交付发送方的报文段,因此,当对先前未确认报文段的确认到达时,能够增加发送方的速率。
-
带宽探测。为探测拥塞开始出现的速率,TCP 发送方增加它的传输速率,从该速率后退,进而再次开始探测,看看拥塞开始速率是否发生了变化。
-
TCP拥塞控制算法:①慢启动;②拥塞避免;③快速恢复。
-
慢启动
慢启动(slow-start)状态,cwnd的值以1个MSS开始并且每当传输的报文段首次被确认就增加1个MSS。TCP向网络发送第一个报文段并等待一个确认。当该确认到 达时,TCP发送方将拥塞窗口增加一个MSS,并发送出两个最大长度的报文段。这两个报文段被确认,则发送方对每个确认报文段将拥塞窗口增加一个MSS,使得拥塞窗口变为4个MSS,并这样下去。这一过程每过一个RTT,发送速率就翻番。因此,TCP 发送速率起始慢,但在慢启动阶段以指数增长。
但是如何结束这种指数增长呢?
首先,如果存在一个由超时指示的丢包事件(即拥塞),TCP发送方将cwnd设置为1并重新开始慢启动过程。它还将第二个状态变量ssthresh(慢启动阈值)设置为cwnd/2,即当检到拥塞时将ssthresh置为拥塞控制窗口值的一半。
慢启动结束的第二种方式是直接与ssthresh的值相关联。当达到ssthresh,结束慢启动并且TCP转移到拥塞避免模式。当进入拥塞避免模式,TCP更为谨慎的增加cwnd。
最后一种结束慢启动的方式是,如果检测到3个冗余的ACK,这是TCP执行一种快速重传并且进入快速恢复状态。
- 拥塞避免
一旦进入拥塞避免状态,cwnd的值大约是上次遇到拥塞时的值的一半,即距离拥塞可能并不遥远!因此,TCP无法每过一个RTT再将cwnd的值翻番,而是采用了一种较为保守的方法,每个RTT只将cwnd的值增加一个MSS。
- 快速恢复
但是何时应当结束拥塞避免的线性增长(每RTT 1MSS)呢?当出现超时时,TCP的拥塞避免算法行为相同。与慢启动的情况一样,cwnd的值被设置为1个MSS,当丢包事件出现时,ssthresh的值被更新为cwnd值的一半。
公平性
考虑K条TCP连接,每条都有不同的端到端路径,但是都经过一段传输速率为Rbps的瓶颈链路。(所谓瓶颈链路,是指对于每条连接,沿着该连接路径上的所有其他段链路都不拥塞,而且与该瓶颈链路的传输容量相比,它们都有充足的传输容量。)假设每条连接都在传输一个大文件,而且无UDP流量通过该段瓶颈链路。如果每条连接的平均传输速率接近尺R/K,即每条连接都得到相同份额的链路带宽,则认为该拥塞控制机制是公平的。
- 公平性和UDP
我们刚才已经看到,TCP拥塞控制是如何通过拥塞窗口机制来调节一个应用程序的传输速率的。许多多媒体应用如因特网电话和视频会议,经常就因为这种特定原因而不在TCP上运行,因为它们不想其传输速率被扼制,即使在网络非常拥塞的情况下。相反,这些应用宁可在UDP上运行,UDP是没有内置的拥塞控制的。当运行在UDP上时,这些应用能够以恒定的速率将其音频和视频数据注入网络之中并且偶尔会丢失分组,而不愿在拥塞时将其发送速率降至“公平”级别并且不丢失任何分组。从TCP的观点来看,运行在UDP上的多媒体应用是不公平的,因为它们不与其他连接合作,也不适时地调整其传输速率。因为TCP拥塞控制在面临拥塞增加(丢包)时,将降低其传输速率,而 UDP源则不必这样做,UDP源有可能压制TCP流量。当今的一个主要研究领域就是开发一种因特网中的拥塞控制机制,用于阻止UDP流量不断压制直至中断因特网吞吐量的情况。
- 公平性和并并行TCP连接
即使我们能够迫使UDP流量具有公平的行为,但公平性问题仍然没有完全解决。这是因为我们没有什么办法阻止基于TCP的应用使用多个并行连接。例如,Web浏览器通常使用多个并行TCP连接来传送一个Web页中的多个对象。(多条连接的确切数目可以在多数浏览器中进行配置。)当一个应用使用多条并行连接时,它占用了一条拥塞链路中较大比例的带宽。举例来说,考虑一段速率为尺且支持9 个在线客户-服务器应用的链路,每个应用使用一条TCP连接。如果一个新的应用加入进来,也使用一条TCP连接,则每个 应用得到差不多相同的传输速率R/10。但是如果这个新的应用这次使用了 11个并行TCP 连接,则这个新应用就不公平地分到超过R/2的带宽。Web流量在因特网中是非常普遍的,所以多条并行连接并非不常见。
明确拥塞通告:网络辅助拥塞控制
在网络层,IP数据报首部的服务类型字段中的两个比特(总的说来,有四种可能的值)被用于ECNO路由器所使用的一种ECN比特设置指示该路由器正在历经拥塞。该拥塞指示则由被标记的IP数据报所携带,送给目的主机,再由目的主机通知发送主机。没有提供路由器拥塞时的定义;该判断是由路由器厂商所做的配置选择,并且由网络操作员决定。然而,推荐仅当拥塞持续不断存在时才设置ECN比特。发送主机所使用的另一种ECN比特设置通知路由器发送方和接收方是ECN使能的,因此能够对于ECN指示的网络拥塞采取行动。当接收主机中的TCP通过一个接收到的数据报收到了一个ECN拥塞指示时,接收主机中的TCP通过在接收方到发送方的TCP ACK报文段中设置ECE (明确 拥塞通告回显)比特,通知发送主机中的TCP收到拥塞指示。接下来, TCP发送方通过减半拥塞窗口对一个具有ECE拥塞指示的ACK做出反应,就像它对丢失 报文段使用快速重传做出反应一样,并且在下一个传输的TCP发送方到接收方的报文段首部中对CWR (拥塞窗口缩减)比特进行设置。除了 TCP以外的其他运输层协议也可以利用网络层发送ECN信号。数据报拥塞控制协议(Datagram Congestion Control Protocol,DCCP)提供了一种低开销、控制 拥塞的类似UDP不可靠服务,该协议利用了ECN。DCTCP (数据中心TCP) 是一种专门为数据中心网络设计的TCP版本,也利用了ECN。
至此,我们将运输层详解完毕!