运输层笔记
1、概述和运输层服务
运输层协议为运行在不同主机上的应用进程之间提供了 逻辑通信(logic communication) 功能。
应用进程使用运输层提供的逻辑通信功能彼此发送报文,而无须考虑承载这些报文的
物理基础设施的细节。
运输层协议是在端系统中而不是在路由器中实现的。在发送端,运输
层将从发送应用程序进程接收到的报文转换成运输层分组,用因特网术语来讲该分组称为
运输层 报文段(segment)。实现的方法(可能)是将应用报文划分为较小的块,并为每块
加上一个运输层首部以生成运输层报文段。然后,在发送端系统中,运输层将这些报文段
传递给网络层,网路层将其封装成网络层分组(即数据报)并向目的地发送。注意到下列
事实是重要的:网络路由器仅作用于该数据报的网络层字段;即它们不检查封装在该数据
报的运输层报文段的字段。在接收端,网络层从数据报中提取运输层报文段,并将该报文
段向上交给运输层。运输层则处理接收到的报文段,使该报文段中的数据为接收应用进程
使用。
因特网网络层协议有一个名字叫IP,即网际协议。IP
为主机之间提供了逻辑通信。IP的服务模型是 尽力而为交付服务 (besl eflbrl delivery service)。
这意味着IP尽它“最大的努力”在通信的主机之间交付报文段,但它并不做任何确
保。特别是,它不确保报文段的交付,不保证报文段的按序交付,不保证报文段中数据的
完整性。由于这些原因,IP被称为 不可靠服务 (unreliable service)。在此还要指出的是,
每台主机至少有一个网络层地址,即所谓的IP地址。
UDP和TCP最基本的责任是,将两个端系统间IP的交付服务扩展为运行在端系统上的两
个进程之间的交付服务。将主机间交付扩展到进程间交付被称为 运输层的多路复用
(transport-layer multiplexing)与 多路分解 (demultiplexing)。
UDP和TCP还可以通过在其报文段首部中包括差错检查字段而提
供完整性检查。进程到进程的数据交付和差错检查是两种最低限度的运输层服务,也是
UDP所能提供的仅有的两种服务。特别是,与IP—样,UDP也是一种不可靠的服务,即
不能保证一个进程所发送的数据能够完整无缺地(或全部!)到达目的进程。
另一方面,TCP为应用程序提供了几种附加服务。首先,它提供 可靠数据传输 (relia-
ble data transfer)。通过使用流量控制、序号、确认和定时器(本章将详细介绍这些技术),
TCP确保正确地、按序地将数据从发送进程交付给接收进程。这样,TCP就将两个端系统
间的不可靠IP服务转换成了一种进程间的可靠数据传输服务。TCP还提供 拥塞控制 (com
gestion control)。拥塞控制与其说是一种提供给调用它的应用程序的服务,不如说是一种
提供给整个因特网的服务,这是一种带来通用好处的服务。不太严格地说,TCP拥塞控制
防止任何一条TCP连接用过多流量来淹没通信主机之间的链路和交换设备。TCP力求为每
个通过一条拥塞网络链路的连接平等地共享网络链路带宽。这可以通过调节TCP连接的发
送端发送进网络的流量速率来做到。在另一方面,UDP流量是不可调节的。使用UDP传
输的应用程序可以根据其需要以其愿意的任何速率发送数据。
2、多路复用与多路分解
现在我们考虑接收主机怎样将一个到达的运输层报文段定向到适当的套接字。为此目
的,每个运输层报文段中具有几个字段。在接收端,运输层检查这些字段,标识出接收套
接字,进而将报文段定向到该套接字。将运输层报文段中的数据交付到正确的套接字的工
作称为 多路分解 (demultiplexing)。在源主机从不同套接字中收集数据块,并为每个数据
块封装上首部信息(这将在以后用于分解)从而生成报文段,然后将报文段传递到网络
层,所有这些工作称为 多路复用 (nmhiplexing)。
现在应该清楚运输层是怎样能够实现分解服务的了:在主机上的每个套接字能够分配
一个端口号,当报文段到达主机时,运输层检査报文段中的目的端口号,并将其定向到相
应的套接字。然后报文段中的数据通过套接字进入其所连接的进程。
3、无连接传输:UDP
适合用UDP的几个点:
- 关于发送什么数据以及何时发送的应用层控制更为精细。采用UDP时,只要应用
进程将数据传递给UDP, UDP就会将此数据打包进UDP报文段并立即将其传递给
网络层。在另一方面,TCP有一个拥塞控制机制,以便当源和目的主机间的一条
或多条链路变得极度拥塞时来遏制运输层TCP发送方。TCP仍将继续重新发送数
据报文段直到目的主机收到此报文并加以确认,而不管可靠交付需要用多长时间。- 无需连接建立。
- 无连接状态。TCP需要在端系统中维护连接状态。此连接状态包括接收和发送缓存、
拥塞控制参数以及序号与确认号的参数。- 分组首部开销小。每个TCP报文段都有20字节的首部开销,而UDP仅有8字节
的开销。
3.1、UDP报文段结构

3.2、UDP检验和
UDP检验和提供了差错检测功能。这就是说,检验和用于确定当UDP报文段从源到
达目的地移动时,其中的比特是否发生了改变(例如,由于链路中的噪声干扰或者存储在
路由器中时引入问题)。发送方的UDP对报文段中的所有16比特字的和进行反码运算,
求和时遇到的任何溢出都被回卷。得到的结果被放在UDP报文段中的检验和字段。
4、可靠数据传输原理
在检验和、序号、定时器、肯定和否定确认
分组这些技术中,每种机制都在协议的运行中起到了必不可少的作用。至此,我们得到了
一个可靠数据传输协议!
由于之前的协议是一个停等协议,也就是一个分组发出必须等到一个肯定回答才会接着发送下一个分组,效率太低了。
这种特殊的性能问题的一个简单解决方法是:不以停等方式运行,允许发送方发送多
个分组而无须等待确认。图3-18b显示了如果发送方可以在等
待确认之前发送3个报文,其利用率也基本上提高3倍。因为许多从发送方向接收方输送
的分组可以被看成是填充到一条流水线中,故这种技术被称为 流水线 (pipelining)。流水
线技术对可靠数据传输协议可带来如下影响:
- 必须增加序号范围,因为每个输送中的分组(不计算重传的)必须有一个唯一的
序号,而且也许有多个在输送中的未确认报文。- 协议的发送方和接收方两端也许不得不缓存多个分组。发送方最低限度应当能缓
冲那些已发送但没有确认的分组。如下面讨论的那样,接收方或许也需要缓存那
些已正确接收的分组。- 所需序号范围和对缓冲的要求取决于数据传输协议如何处理丢失、损坏及延时过
大的分组。解决流水线的差错恢复有两种基本方法是: 回退N步 (Go Back N,
GBN)和 选择重传 (Selective Repeat, SR)。
5、面向连接的传输:TCP
TCP是因特网运输层的面向连接的可靠的运输协议。我们在本节中将看到,为了提供可靠数据传
输,TCP依赖于前一节所讨论的许多基本原理,其中包括差错检测、重传、累积确认、定
时器以及用于序号和确认号的首部字段。
5.1、TCP连接
TCP被称为是 面向连接的 (connection.oriented),这是因为在一个应用进程可以开始
向另一个应用进程发送数据之前,这两个进程必须先相互“握手”,即它们必须相互发送
某些预备报文段,以建立确保数据传输的参数。作为TCP连接建立的一部分,连接的双方
都将初始化与TCP连接相关的许多TCP状态变量。
一旦建立起一条TCP连接,两个应用进程之间就可以相互发送数据了。我们考虑一下
从客户进程向服务器进程发送数据的情况。如2. 7节中所述,客户进程通过套接字(该进
程之门)传递数据流。数据一旦通过该门,它就由客户中运行的TCP控制了。如图3・28
所示,TCP将这些数据引导到该连接的 发送缓存 (sendbuffer)里,发送缓存是发起三次
握手期间设置的缓存之一。接下来TCP就会不时从发送缓存里取出一块数据,并将数据传
递到网络层。TCP可从缓存中取出并放入报文段中的数据数量受限于 最大报文段长度 (Maximum Segment Size,
MSS)。MSS通常根据最初确定的由本地发送主机发送的最大链路层帧长度(即所谓的
最大传输单元 (Maximum Transmission Unit, MTU))来设置。设置该MSS要保证一个TCP
报文段(当封装在一个IP数据报中)加上TCP/IP首部长度(通常40字节)将适合单个
链路层帧。以太网和PPP链路层协议都具有1500字节的MTU,因此MSS的典型值为1460
字节。
TCP为每块客户数据配上一个TCP首部,从而形成多个 TCP报文段 (TCP segment)。
这些报文段被下传给网络层,网络层将其分别封装在网络层IP数据报中。然后这些IP数
据报被发送到网络中。当TCP在另一端接收到一个报文段后,该报文段的数据就被放入该
TCP连接的接收缓存中。
5.2、TCP报文段结构

与UDP一样,首部包括 源端口号 和 目的端口
号,它被用于多路复用/分解来自或送到上
层应用的数据。另外,同UDP—样,TCP
首部也包括 检验和字段 (checksum field)。
TCP报文段首部还包含下列字段:
- 32比特的 序号字段 (sequence number field)和32比特的 确认号字段 (acknowl
edgment number field)。这些字段被TCP发送方和接收方用来实现可靠数据传输服
务。- 16比特的 接收窗口字段 (receive window field),该字段用于流量控制。我们很快
就会看到,该字段用于指示接收方愿意接受的字节数量。- 4比特的 首部长度字段 (header length field),该字段指示了以32比特的字为单位
的TCP首部长度。由于TCP选项字段的原因,TCP首部的长度是可变的。(通常,
选项字段为空,所以TCP首部的典型长度是20字节。)- 可选与变长的 选项字段 (options field),该字段用于发送方与接收方协商最大报文
段长度(MSS)时,或在高速网络环境下用作窗口调节因子时使用。- 6比特的 标志字段 (flag field)。 ACK比特 用于指示确认字段中的值是有效的,即
该报文段包括一个对已被成功接收报文段的确认。 RST 、 SYN 和 FIN 比特用于连
接建立和拆除,我们将在本节后面讨论该问题。在明确拥塞通告中使用了 CWR 和
ECE 比特。
主机A填充进报文段的确认号是主机A期望从主机B收到的下一字节的序号。
序号和确认号学习的一个示例

一个报文段的序号就是该报文段数据字段首字节的序号。因此,客户发送的第一个报文段的序号为42,服务器发送
的第一个报文段的序号为79。前面讲过,确认号就是主机正在等待的数据的下一个字节序
号。在TCP连接建立后但没有发送任何数据之前,该客户等待字节79,而该服务器等待字节42。
如图3・31中所示,共发送3个报文段。第一个报文段是由客户发往服务器,在它的
数据字段里包含一字节的字符啲ASCII码。如我们刚讲到的那样,第一个报文段的序
号字段里是42。另外,由于客户还没有接收到来自服务器的任何数据,因此该第一个报文
段中的确认号字段中是79。
第二个报文段是由服务器发往客户。它有两个目的:首先它是为该服务器所收到数据
提供一个确认。通过在确认号字段中填入43,服务器告诉客户它已经成功地收到字节42
及以前的所有字节,现在正等待着字节43的出现。该报文段的第二个目的是回显字符
'C'。因此,在第二个报文段的数据字段里填入的是字符'c'的ASCII码。第二个报文段
的序号为79,它是该TCP连接上从服务器到客户的数据流的起始序号,这也正是服务器
要发送的第一个字节的数据。
第三个报文段是从客户发往服务器的。它的唯一目的是确认已从服务器收到的数据。
该报文段的数据字段为空。该报文段的确认号字段填入的是80,因为客户已经收到了字节
流中序号为79及以前的字节,它现在正等待着字节80的出现。你可能认为这有点奇怪,
即使该报文段里没有数据还仍有序号。这是因为TCP存在序号字段,报文段需要填入某个序号。
5.3、可靠数据传输
TCP在IP不可靠的尽力而为服务之上创建了一种 可靠数据传输服务。
TCP的可靠数据传输服务确保一个进程从其接收缓存中读出的数据流是
无损坏、无间隙、非冗余和按序的数据流;即该字节流与连接的另一方端系统发送出的字
节流是完全相同。
因为发送方经常一个接一个地发送大量的报文段,如果一个报文段丢失,就很可能引
起许多一个接一个的冗余ACK。如果TCP发送方接收到对相同数据的3个冗余ACK,它
把这当作一种指示,说明跟在这个已被确认过3次的报文段之后的报文段已经丢失。
一旦收到3个冗余ACK, TCP就执行 快速重传 (fast retransmit)
5.4、TCP连接管理
假设运行
在一台主机(客户)上的一个进程想与另一台主机(服务器)上的一个进程建立一条连
接。客户应用进程首先通知客户TCP,它想建立一个与服务器上某个进程之间的连接。客
户中的TCP会用以下方式与服务器中的TCP建立一条TCP连接:
- 第一步: 客户端的TCP首先向服务器端的TCP发送一个特殊的TCP报文段。该报
文段中不包含应用层数据。但是在报文段的首部(参见图3-29)中的一个标志位
(即SYN比特)被置为1。因此,这个特殊报文段被称为SYN报文段。另外,客
户会随机地选择一个初始序号(client_isn),并将此编号放置于该起始的TCP SYN
报文段的序号字段中。该报文段会被封装在一个IP数据报中,并发送给服务器。- 第二步: 一旦包含TCP SYN报文段的IP数据报到达服务器主机(假定它的确到达
了!),服务器会从该数据报中提取出TCP SYN报文段,为该TCP连接分配TCP缓
存和变量,并向该客户TCP发送允许连接的报文段。这个允许连接的报文段也不包含应用层数据。但是,在报文段
的首部却包含3个重要的信息。首先,SYN比特被置为1。其次,该TCP报文段
首部的确认号字段被置为client_isn + 1。最后,服务器选择自己的初始序号
(serverjsn),并将其放置到TCP报文段首部的序号字段中。这个允许连接的报文
段实际上表明了:
“我收到了你发起建立连接的SYN分组,该分组带有初始序号
client_isn。我同意建立该连接。我自己的初始序号是server_isn。该允许连接的报
文段被称为 SYNACK报文段 (SYNACK segment)。- 第三步: 在收到SYNACK报文段后,客户也要给该连接分配缓存和变量。客户主
机则向服务器发送另外一个报文段;这最后一个报文段对服务器的允许连接的报
文段进行了确认(该客户通过将值server_isn + 1放置到TCP报文段首部的确认字
段中来完成此项工作)。因为连接已经建立了,所以该SYN比特被置为0。该三次
握手的第三个阶段可以在报文段负载中携带客户到服务器的数据。
一旦完成这3个步骤,客户和服务器主机就可以相互发送包括数据的报文段了。在
以后每一个报文段中,SYN比特都将被置为0。注意到为了创建该连接,在两台主机之
间发送了 3个分组,如图3・39所示。由于这个原因,这种连接创建过程通常被称为 3次握手 (three-way handshake)。
天下没有不散的宴席,对于TCP连接也是如此。参与一条TCP连接的两个进程中的
任何一个都能终止该连接。当连接结束后,主机中的“资源”(即缓存和变量)将被
客户释放。举一个例子,假设某客户打算关闭连接,如图3-40所示。客户应用进程发出
一个关闭连接命令。这会引起客户TCP向服务器进程发送一个特殊的TCP报文段。
这个特殊的报文段让其首部中的一个标志位即FIN比特(参见图3-29)被设置为
l。当服务器接收到该报文段后,就向发送方回送一个确认报文段。然后,服务器发
送它自己的终止报文段,其FIN比特被置为1。最后,该客户对这个服务器的终止
报文段进行确认。此时,在两台主机上用于该连接的所有资源都被释放了。
在一个TCP连接的生命周期内,运行在每台主机中的TCP协议在各种 TCP状态 (TCP state)之间变迁。图3・41说明了
客户TCP会经历的一系列典型TCP状态。服务器图 3-40 关闭一条TCP连接
客户TCP开始时处于 CLOSED (关闭)状态。 客户的应用程序发起一个新的TCP连接
(可通过在第2章讲过的Python例子中创建一个Socket对象来完成)。这引起客户中的TCP
向服务器中的TCP发送一个SYN报文段。在发送过SYN报文段后,客户TCP进入了 SYN_SENT
状态。当客户TCP处在SYN_SENT状态时,它等待来自服务器TCP的对客户所发报
文段进行确认且SYN比特被置为1的一个报文段。收到这样一个报文段之后,客户TCP
进入 ESTABLISHED (已建立)状态。当处在ESTABLISHED状态时,TCP客户就能发送和
接收包含有效载荷数据(即应用层产生的数据)客户应用程序发起的TCP报文段了。
假设客户应用程序决定要关闭该连接。(注意到服务器也能选择关闭该连接。)这引起
客户TCP发送一个带有FIN比特被置为1的TCP报文段,并进入 FIN_WAIT_1 状态。当处
在FIN_WAIT_1状态时,客户TCP等待一个来自服务器的带有确认的TCP报文段。当它收
到该报文段时,客户TCP进入 FIN_WAIT_2 状态。当处在FIN_WAIT_2状态时,客户等待
来自服务器的FIN比特被置为1的另一个报文段;当收到该报文段后,客户TCP对服务器
的报文段进行确认,并进入 TIME_WAIT 状态。假定ACK丢失,TIME_WAIT状态使TCP
客户重传最后的确认报文。在TIME_WAIT状态中所消耗的时间是与具体实现有关的,而
典型的值是30秒、1分钟或2分钟。 经过等待后,连接就正式关闭,客户端所有资源(包
括端口号)将被释放。

我们上面的讨论假定了客户和服务器都准备通信,即服务器正在监听客户发送其SYN
报文段的端口。我们来考虑当一台主机接收到一个TCP报文段,其端口号或源IP地址与
该主机上进行中的套接字都不匹配的情况。例如,假如一台主机接收了具有目的端口 80
的一个TCP SYN分组,但该主机在端口 80不接受连接(即它不在端口 80上运行Web服
务器)。则该主机将向源发送一个特殊重置报文段。该TCP报文段将RST标志位(参见
3.5.2节)置为1。因此,当主机发送一个重置报文段时,它告诉该源“我没有那个报文
段的套接字。请不要再发送该报文段了”。
对一台主机的目的端口 6789发送一个特殊的TCP SYN报文段。有3种可能的输出:
- 源主机从目标主机接收到一个TCP SYNACK报文段。 因为这意味着在目标主机上
一个应用程序使用TCP端口 6789运行,nnrnp返回“打开”。- 源主机从目标主机接收到一个TCP RST报文段。 这意味着该SYN报文段到达了目
标主机,但目标主机没有运行一个使用TCP端口 6789的应用程序。但攻击者至少
知道发向该主机端口 6789的报文段没有被源和目标主机之间的任何防火墙所阻挡。- 源什么也没有收到。 这很可能表明该SYN报文段被中间的防火墙所阻挡,无法到
达目标主机。
6、拥塞控制原理
6.1、拥塞原因与代价
- 当分组的到达速率接近链路容量时,分组经历巨大的排队时延。
- 发送方必须执行重传以补偿因为缓存溢出而丢弃(丢失)的分组。
- 发送方在遇到大时延时所进行的不必要重传会引起路由器利用其链路带宽来转发不必要的分组副本。
- 当一个分组沿一条路径被丢弃时,每个上游路由器用于转发该分组到丢弃该分组而使用的传输容量最终被浪费掉了。
6.2、拥塞控制方法
- 端到端拥塞控制。 在端到端拥塞控制方法中,网络层没有为运输层拥塞控制提供
显式支持 。即使网络中存在拥塞,端系统也必须通过对网络行为的观察(如分组
丢失与时延)来推断之。TCP采用端到端的方法解决拥塞控制,因为IP层不会向端系统
提供有关网络拥塞的反馈信息。TCP报文段的丢失(通过超时或3次冗余确认而得知)被认为是
网络拥塞的一个迹象,TCP会相应地减小其窗口长度。- 网络服务的拥塞控制。在网络辅助的拥塞控制中,路由器向发送方提供关于网络
中拥塞状态的显式反馈信息。
7、TCP拥塞控制
TCP所采用的方法是让每一个发送方根据所感知到的网络拥塞程度来限制其能向
连接发送流量的速率。如果一个TCP发送方感知从它到目的地之间的路径上没什么拥
塞,则TCP发送方增加其发送速率;如果发送方感知沿着该路径有拥塞,则发送方就
会降低其发送速率。但是这种方法提出了三个问题。第一,一个TCP发送方如何限制
它向其连接发送流量的速率呢?第二,一个TCP发送方如何感知从它到目的地之间的
路径上存在拥塞呢?第三,当发送方感知到端到端的拥塞时,采用何种算法来改变其
发送速率呢?
TCP发送方如何限制发送流量的速率:运行在发送方的TCP拥塞控制机制跟踪一个额外的变量,即拥塞窗口
(congestion window)。拥塞窗口表示为cwnd,它对一个TCP发送方能向网络中发送流量的
速率进行了限制。
TCP发送方如何感知从它到目的地之间的路径上存在拥塞:我们将一个TCP发送方的“丢包事件”定义为:
要么出现超时,要么收到来自接收方的3个冗余ACK。当出现过度的拥塞时,在沿着这条路径上的一台(或多
台)路由器的缓存会溢出,引起一个数据报(包含一个TCP报文段)被丢弃。丢弃的数
据报接着会引起发送方的丢包事件(要么超时或收到3个冗余ACK),发送方就认为在发
送方到接收方的路径上出现了拥塞的指示。
TCP发送方采用何种算法来改变其发送速率:TCP使用下列指导性原则回答这些问题:
- 一个丢失的报文段表意味着拥塞,因此当丢失报文段时应当降低TCP发送方的速率。
- 一个确认报文段指示该网络正在向接收方交付发送方的报文段,因此,当对先前
未确认报文段的确认到达时,能够增加发送方的速率。- 带宽探测。给定ACK指示源到目的地路径无拥塞,而丢包事件指示路径拥
塞,TCP调节其传输速率的策略是增加其速率以响应到达的ACK,除非岀现
丢包事件,此时才减小传输速率。因此,为探测拥塞开始出现的速率,TCP
发送方增加它的传输速率,从该速率后退,进而再次开始探测,看看拥塞开
始速率是否发生了变化。TCP发送方的行为也许类似于要求(并得到)越来
越多糖果的孩子,直到最后告知他/她“不行!”,孩子后退一点,然后过一会
儿再次开始提出请求。
TCP拥塞控制算法包括3个主要部分:1、慢启动;2、拥塞避免;3、快速恢复。
慢启动和拥塞避免是TCP的强制部分,两者的差异在于对收到的ACK
做出反应时增加cwnd长度的方式。我们很快将会看到慢启动比拥塞避免能更快地增
加cwnd的长度(不要被名称所迷惑!)。快速恢复是推荐部分,对TCP发送方并非是
必需的。1. 慢启动
首先将cwnd设置成一个MSS(最大报文段长度)的较小值,之后每过一个RTT(往返时延),
发送速率就翻番。因此,TCP发送速率起始慢,但在慢启动阶段以指数增长。
但是,何时结束这种指数增长呢?慢启动对这个问题提供了几种答案。首先,
如果存在一个由超时指示的丢包事件(即拥塞),TCP发送方将cwnd设置为1并重
新开始慢启动过程。它还将第二个状态变量的值ssthresh ("慢启动阈值”的速记)
设置为cwnd/2 ,即当检测到拥塞时将ssthresh置为拥塞窗口值的一半。慢启动结束的
第二种方式是直接与ssthresh的值相关联。因为当检测到拥塞时ssthresh设为cwnd的值
一半,当到达或超过ssthresh的值时,继续使cwnd翻番可能有些鲁莽。因此,当cwnd
的值等于ssthresh时,结束慢启动并且TCP转移到拥塞避免模式。我们将会看到,当
进入拥塞避免模式时,TCP更为谨慎地增加cwndo最后一种结束慢启动的方式是,
如果检测到3个冗余ACK,这时TCP执行一种快速重传(参见3. 5. 4节)并进入快
速恢复状态。2. 拥塞避免
一旦进入拥塞避免状态,cwnd的值大约是上次遇到拥塞时的值的一半,即距离拥塞
可能并不遥远!因此,TCP无法每过一个RTT再将cwnd的值翻番,而是采用了一种较为
保守的方法,每个RTT只将cwnd的值增加一个MSS [RFC 5681]。这能够以几种方式完
成。一种通用的方法是对于TCP发送方无论何时到达一个新的确认,就将cwnd增加一个
MSS ( MSS/cwnd)字节。
但是何时应当结束拥塞避免的线性增长(每RTT 1MSS)呢?当出现超时时,TCP的
拥塞避免算法行为相同。与慢启动的情况一样,cwnd的值被设置为1个MSS,当丢包事件
出现时,ssthresh的值被更新为cwnd值的一半。然而,前面讲过丢包事件也能由一个三个
冗余ACK事件触发。在这种情况下,网络继续从发送方向接收方交付报文段(就像由收
到冗余ACK所指示的那样)。因此TCP对这种丢包事件的行为,相比于超时指示的丢包,
应当不那么剧烈:TCP将cwnd的值减半(为使测量结果更好,计及已收到的3个冗余的
ACK要加上3个MSS),并且当收到3个冗余的ACK,将ssthresh的值记录为cwnd的值的
一半。接下来进入快速恢复状态。3、快速恢复
在快速恢复中,对于引起TCP进入快速恢复状态的缺失报文段,对收到的每个冗余的
ACK, cwnd的值增加一个MSS。最终,当对丢失报文段的一个ACK到达时,TCP在降低
cwnd后进入拥塞避免状态。如果出现超时事件,快速恢复在执行如同在慢启动和拥塞避
免中相同的动作后,迁移到慢启动状态:当丢包事件出现时,cwnd的值被设置为1个
MSS,并且ssthresh的值设置为 cwnd值的一半。4、TCP拥塞控制:回顾
在深入了解慢启动、拥塞避免和快速恢复的细节后,现在有必要退回来回顾一下全
局。忽略一条连接开始时初始的慢启动阶段,假定丢包由3个冗余的ACK而不是超时指
示,TCP的拥塞控制是:每个RTT内cwnd线性(加性)增加1MSS,然后出现3个冗余
ACK事件时cwncl减半(乘性减)。因此,TCP拥塞控制常常被称为 加性增、乘性减
(Additive- Increase, Multiplicative- Decrease,在图3-53中所示的“锯齿”行为,这也
很好地图示了我们前面TCP检测带宽时的直觉,即TCP线性地增加它的拥塞窗
口长度(因此增加其传输速率),直到出现3个冗余ACK事件。然后以2个因子
来减少它的拥塞窗口长度,然后又开始了线性增长,探测是否还有另外的可用带宽。








浙公网安备 33010602011771号