传输层提供的服务
传输层的功能
传输层向它上面的应用层提供通信服务,它是面向通信部分的最高层,也是用户功能中的最低层
传输层位于网络层之上,它为运行在不同主机上的进程之间提供了逻辑通信,而网络层提供主机之间的逻辑通信
只有主机的协议栈才有传输层和应用层,而路由器在转发分组时都只用到下三层的功能(通信子网中没有传输层)

传输层的功能如下:
传输层提供应用进程之间的逻辑通信,即端到端通信;而网络层提供的是主机之间的逻辑通信
复用和分用:
- 复用:发送方不同的应用进程都可使用同一个传输层协议传送数据
- 分用:接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程
注意:网络层也有复用分用的功能:
- 复用:发送方不同协议的数据都可以封装成 IP 数据报发送出去
- 分用:接收方的网络层在剥去首部后把数据交付给相应的协议
传输层还要对收到的整个报文进行差错检测;而网络层只检查 IP 数据报的首部
提供两种不同的传输协议,即面向连接的 TCP 和无连接的 UDP;而网络层无法同时提供
传输层向高层用户屏蔽了低层网络核心的细节,让进程间存在一条逻辑通信信道,但使用的协议不同也会有很大差别:
采用 TCP 时,这种逻辑通信信道就相当于一条全双工的可靠信道
采用 UDP 时,这种逻辑通信信道仍然是一条不可靠信道
传输层的寻址与端口
端口的作用
应用进程将数据通过端口交付给传输层,传输层将数据通过端口交付给应用进程,端口是传输层服务访问点 TSAP
在协议栈层间的抽象的协议端口是软件端口,它与路由器的硬件端口是完全不同的概念:
- 硬件端口:不同硬件设备进行交互的接口
- 软件端口:应用层的各种协议进程与传输实体进行层间交互的一种地址
传输层使用的是软件端口
端口号
应用进程通过端口号进行标识,端口号长度为 16bit,能够表示 65536 个不同的端口号
端口号只具有本地意义,在因特网中,不同计算机的相同端口号是没有联系的
根据端口号范围可将端口分为两类:
服务器端使用的端口号,它又分为两类:
熟知端口号:数值为 0 ~ 1023,互联网地址指派机构
IANA把这些端口号指派给了 TCP/IP 最重要的一些应用程序一些常用的熟知端口号如下:

登记端口号:数值为 1024 ~ 49151,供没有熟知端口号的应用程序使用
客户端使用的端口号,短暂端口号:数值为 49152 ~ 65535,这类端口号仅在客户进程运行时才动态地选择
通信结束后,刚用过的客户端口号就不复存在,从而这个端口号就可供其他客户进程以后使用
套接字
通过 IP 地址来找到主机,通过端口号找到应用进程;端口号拼接到 IP 地址即构成套接字 Socket
在网络中采用发送方和接收方的套接字来识别端点,套接字 Socket = (IP 地址, 端口号),它唯一地标识网络中的一个端点
在网络通信中,主机 A 发给主机 B 的报文段包含目的端口号和源端口号,源端口号是返回地址的一部分
无连接服务与面向连接服务
- 面向连接服务:通信前建立连接,通信中实时地监控和管理连接,通信结束释放连接
- 无连接服务:通信不需要建立连接;通信时,直接发送信息,尽力而为地往目的地传送
TCP/IP 协议族在 IP 层之上使用了两个传输协议:
面向连接的传输控制协议 TCP:传输层向上提供的是一条全双工的可靠逻辑信道
TCP 不提供广播或组播服务,由于提供了面向连接的可靠传输服务,因此增加了许多开销
这不仅使协议数据单元的头部增大很多,还要占用许多的处理机资源
因此 TCP 主要适用于可靠性更重要的场合,如 FTP、HTTP、TELNET 等
无连接的用户数据报协议 UDP:传输层向上提供的是一条不可靠的逻辑信道
UDP 在 IP 之上仅提供多路复用和对数据的错误检查两个附加服务
UDP 在传送数据之前不需要先建立连接,远程主机的传输层收到 UDP 报文后,不需要给出任何确认
由于 UDP 比较简单,因此执行速度比较快、实时性好,使用 UDP 的应用主要包括
TFTP、DNS、SNMP、RTP
UDP 协议
UDP 数据报
UDP 概述
UDP 仅在 IP 的数据报服务之上增加了两个最基本的服务:复用和分用以及差错检测
如果应用开发者选择 UDP 而非 TCP,那么应用程序几乎直接与 IP 打交道,但 UDP 具有如下优点:
UDP 无须建立连接,因此 UDP 不会引入建立连接的时延
UDP 不维护连接状态,也不跟踪拥塞控制等参数,某些专用应用服务器使用 UDP 时,能支持更多的活动客户机
分组首部开销小,TCP 有
20B的首部开销,而 UDP 仅有8B的开销应用层能更好地控制要发送的数据和发送时间,UDP 没有拥塞控制,因此网络中的拥塞不会影响主机的发送效率
某些实时应用要求以稳定的速度发送,能容忍一些数据的丢失,但不允许有较大的时延,而 UDP 正好满足需求
UDP 支持一对一、一对多、多对一和多对多的交互通信
UDP 常用于一次性传输较少数据的网络应用;UDP 也常用于多媒体应用,如实时视频会议(UDP 延迟小)
UDP 不保证可靠交付,但这并不意味着应用对数据的要求是不可靠的,所有维护可靠性的工作可由用户在应用层来完成
UDP 是面向报文的,发送方 UDP 对应用层交下来的报文,在添加首部后就向下交付给 IP 层;接收方 UDP 对 IP 层交上来 UDP 数据报,在去除首部后就原封不动地交付给上层应用进程;因此,应用程序必须选择合适大小的报文
UDP 的首部格式
UDP 数据报包含两部分:UDP 首部和用户数据,UDP 首部有 8B,由 4 个字段组成,每个字段的长度都是 2B
各字段意义如下:
- 源端口:源端口号,在需要对方回信时选用,不需要时可用全 0
- 目的端口:目的端口号,必须使用
- 长度:UDP 数据报的长度,包括首部和数据,其最小值是 8
- 校验和:检测 UDP 数据报在传输中是否有错,有错就丢弃;可选字段,不使用时,则直接令该字段为全 0

当传输层从 IP 层收到 UDP 数据报时,就根据首部中的目的端口,把 UDP 数据报通过相应的端口上交给应用进程
如果接收方 UDP 发现不存在对应于目的端口号的应用进程,那么就丢弃该报文,并由 ICMP 发送端口不可达

UDP 校验
在计算校验和时,要在 UDP 数据报之前增加 12B 的伪首部:
- 伪首部只是在计算校验和时,临时添加在 UDP 数据报的前面,得到一个临时的 UDP 数据报
- 校验和就是按照这个临时的 UDP 数据报来计算的
- 伪首部既不向下传送又不向上递交,而只是为了计算校验和
下面是伪首部的格式:

UDP 校验和的计算方法和 IP 数据报首部校验和的计算方法相似:
发送方首先把全零放入校验和字段并添加伪首部,其中 UDP 数据报必须是偶数个字节
若 UDP 数据报的数据部分不是偶数个字节,则要在末尾填入一个全零字节(不发送)
然后按二进制反码计算出这些 16 位字的和,将此和的二进制取反码再写入校验和字段,并发送
直接相加,若加法时发生溢出时,要加 1,结果取反后写入校验字段;使用 16 进制来相加会简单很多
接收方把收到的 UDP 数据报加上伪首部后,按二进制反码求这些 16 位字的和
无差错时其结果应为全 1,否则就表明有差错出现,接收方就应该丢弃这个 UDP 数据报
下图为例子:UDP 数据报的长度是 15B,因此需要添加一个全 0 字节:

注意:
- 校验时,若 UDP 数据报部分的长度不是偶数个字节,则需填入一个全 0 字节,此字节是不发送的
- 如果校验出 UDP 数据报是错误的,可以丢弃或交付给上层,但交付时需要附上错误报告
这种简单的差错检验方法的检错能力并不强,但它的好处是简单、处理速度快
TCP 协议
TCP 协议的特点
TCP 是在不可靠的 IP 层之上实现的可靠的数据传输协议,它的主要特点如下:
- TCP 是面向连接的传输层协议
- 每条 TCP 连接只能有两个端点,每条 TCP 连接只能是点对点的
- TCP 提供可靠的交付服务,保证传送的数据无差错、不丢失、不重复且有序
- TCP 提供全双工通信,为此 TCP 连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据
- 发送缓存用来暂时存放以下数据:TCP 准备发送的数据;TCP 已发送但尚未收到确认的数据
- 接收缓存用来暂时存放以下数据:按序到达但尚未被接收应用程序读取的数据;不按序到达的数据
- TCP 是面向字节流的,它把应用程序交下来的数据仅视为一连串的无结构的字节流
注意:UDP 报文的长度由发送应用进程决定;TCP 报文的长度则根据接收方给出的窗口值和当前网络拥塞程度来决定
如果应用进程传送到 TCP 缓存的数据块太长,TCP 就把它划分得短一些再传送;如果太短,TCP 也可以等到积累足够多的字节后再组成报文段发送出去
TCP 报文段
TCP 传送的数据单元称为报文段,TCP 报文段可以用来运载数据、建立连接、释放连接和应答
一个 TCP 报文段分为首部和数据两部分,整个 TCP 报文段作为 IP 数据报的数据部分封装在 IP 数据报中
首部的前 20B 是固定的,TCP 报文段的首部最短为 20B,后面有 4N 字节是根据需要而增加的选项,长度为 4B 的整数倍

TCP 的全部功能体现在其首部的各个字段中,各字段意义如下:
源端口和目的端口:各占
2B,和 UDP 端口作用一样序号:占
4B,范围为,本报文段所发送的数据的第一个字节的序号 确认号:占
4B,期望收到对方下一个报文段的第一个数据字节的序号若确认号为 N,则表明到序号 N - 1 为止的所有数据都已正确收到
数据偏移,即首部长度:占 4 位,表示首部长度,它指出 TCP 报文段的数据起始位置,数据偏移的单位是 32 位
保留:占 6 位,保留为今后使用,但目前应置为 0
紧急位
URG:URG= 1 时,表明紧急指针字段有效,它告诉系统此报文段中有紧急数据,应尽快传送(发送方使用)但
URG需要和紧急指针配合使用,即数据从第一个字节到紧急指针所指字节就是紧急数据确认位 ACK:仅当 ACK = 1 时确认号字段才有效;TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1
推送位
PSH:接收方 TCP 收到PSH= 1 的报文段,就尽快地交付给接收应用进程,不用等到缓存填满后再向上交付复位位
RST:RST= 1 时,表明 TCP 连接中出现严重差错,必须释放连接,然后再重新建立运输连接同步位 SYN:同步 SYN = 1 表示这是一个连接请求或连接接受报文
当 SYN = 1,ACK = 0 时,表明这是一个连接请求报文;若对方同意建立连接,则在响应报文中使用 SYN = 1,ACK = 1
终止位 FIN:用来释放一个连接,当 FIN = 1 时,表明数据已发送完毕,并要求释放传输连接
窗口:占
2B,范围为,它指出现在允许对方发送的数据量 接收方的数据缓存空间是有限的,因此用窗口值作为接收方让发送方设置其发送窗口的依据
注意:滑动窗口过大会产生过多的 ACK,而过小会使路由器变得拥塞,导致主机丢失分组
校验和:占
2B,检验的范围包括首部和数据两部分,计算方法和 UDP 一样,唯一不同是伪首部的第 4 字段是 6紧急指针:占
2B,仅在URG= 1 时才有意义,它指出在本报文段中紧急数据共有多少字节选项:长度可变,TCP 最初只有最大报文段长度 MSS 一种选项,MSS 是 TCP 报文段中的数据字段的最大长度
填充:使整个首部长度是
4B的整数倍
思考:TCP 没有长度字段是因为在 IP 上给出分组的长度,减一下就得到 TCP 的长度,UDP 那个长度字段是冗余的
TCP 连接管理
TCP 是面向连接的协议,因此每个 TCP 连接都有三个阶段:连接建立、数据传送、连接释放
在 TCP 连接建立的过程中,要解决以下三个问题:
- 要使每一方能够确知对方的存在
- 要允许双方协商一些参数,如最大窗口值、时间戳选项等
- 能够对运输实体资源进行分配,如缓存大小等
TCP 把连接作为最基本的抽象,每条 TCP 连接有两个端点,TCP 连接的端点为套接字 socket 或插口
TCP 连接的建立采用 C/S 方式,主动发起连接建立的应用进程称为客户,而被动等待连接建立的应用进程称为服务器
TCP 连接的建立
连接的建立经历以下 3 个步骤,通常称为三次握手:

连接建立前,服务器进程处于 LISTEN 状态,等待客户的连接请求:
客户机的 TCP 首先向服务器的 TCP 发送连接请求报文段
这个特殊报文段的首部中的同步位 SYN 置 1,同时选择一个初始序号 seq = x
SYN 报文段不能携带数据,但要消耗掉 1 个序号;TCP 客户进程进入同步已发送 SYN-SENT 状态
服务器的 TCP 收到连接请求报文段后,如同意建立连接,则向客户机发回确认,并为该 TCP 连接分配缓存和变量
在确认报文段中,把 SYN 位和 ACK 位都置 1,确认号是 ack = x + 1,同时选择一个初始序号 seq = y
确认报文段不能携带数据,但要消耗掉 1 个序号;TCP 服务器进程进入同步收到
SYN-RCVD状态当客户机收到确认报文段后向服务器给出确认,并为该 TCP 连接分配缓存和变量
确认报文段的 ACK 位置 1,确认号 ack = y + 1,序号 seq = x + 1
该报文段可以携带数据,若不携带数据则不消耗序号;TCP 家无过列结患入已建立连接 ESTABLISHED 状态
TCP 提供的是全双工通信,因此通信双方的应用进程在任何时候都能发送数据
注意:由于服务器比客户端早一步分配资源,这就使得服务器易于受到 SYN 洪泛攻击
额外:若采用两次握手:若客户端向服务端的连接请求在某个结点长时间滞留,客户端再次连接并完成传输后断开,这时滞留的连接请求到达服务端,服务端返回确认报文段,但客户端认为无效并丢弃,但服务端认为连接建立,就白白消耗了资源
额外:若序号都从 1 开始:假设带数据的报文段滞留,在下个连接才到,序号又刚好在新连接的窗口内,从而被收下导致结果错误,因此新连接的序号一定要和前面的连接用过的序号不同
TCP 连接的释放
TCP 连接释放的过程通常称为四次握手,两边都能终止连接:

客户机关闭连接时,向其 TCP 发送连接释放报文段,并停止发送数据,主动关闭 TCP 连接
该报文段的终止位 FIN 置 1,序号 seq = u,它是最后一个字节的序号加 1
FIN 报文段即使不携带数据,消耗掉 1 个序号;TCP 客户进程进入终止等待1 FIN-WAIT-1 状态
服务器收到连接释放报文段后即发出确认
确认号 ack = u + 1,序号 seq = v,它是最后一个字节的序号加 1
然后服务器进入关闭等待 CLOSE-WAIT 状态;客户机到服务器这个方向的连接就释放了
若服务器没有要发送的数据了,此时发出 FIN = 1,序号 seq = w 的连接释放报文段
还须重复上次已发送的确认号 ack = u + 1;服务器进入最后确认 LAST-ACK 状态
客户机收到连接释放报文段后,必须发出确认
把确认报文段中的确认位 ACK 置 1,确认号 ack = w + 1,序号 seq = u + 1
经过时间最长报文段寿命
2MSL后,客户机才进入连接关闭 CLOSED 状态额外:等待
2MSL是为了防止确认报文段丢失,不然丢失后服务器会一直重发,客户端关闭了也收不到
总结
- 连接建立,分为 3 步:
- SYN = 1,seq = x
- SYN = 1,ACK = 1,seq = y,ack = x + 1
- ACK = 1,seq = x + 1,ack = y + 1
- 释放连接,分为 4 步:
- FIN = 1,seq = u
- ACK = 1,seq = v,ack = u + 1
- FIN = 1,ACK = 1,seq = w, ack = u + 1
- ACK = 1,seq = u + 1,ack = w + 1
TCP 可靠传输
TCP 的任务是在 IP 层上建立一种可靠数据传输服务,保证接收方进程收到的字节流与发送方发出的字节流完全一样
TCP 使用了校验、序号、确认和重传等机制来达到这一目的,其中 TCP 的校验机制与 UDP 校验一样
序号
TCP 首部的序号字段用来保证数据能有序提交给应用层,TCP 把数据视为一个无结构但有序的字节流
TCP 连接传送的数据流中的每个字节都编上一个序号,序号字段的值是指本报文段所发送的数据的第一个字节的序号
如下图,发送缓冲区共有 10B,序号从 0 开始,第一个报文段的序号是 0,第二个报文的的序号是 3

确认
TCP 首部的确认号是期望收到对方的下一个报文段的数据的第一个字节的序号,TCP 默认使用累计确认
下图中,如果接受了第一个报文段,那么发送的确认号为 3

发送方缓存区会继续存储那些已发送但未收到确认的报文段,以便在需要时重传
注意:TCP 采用的是对报文段的确认机制,因为它是对每个报文段进行确认,而不是对每个字节进行确认
重传
有两种事件会导致 TCP 对报文段进行重传:超时和冗余 ACK
选择题:分组重传的最大值是发送方能发送的最大值,等于滑动窗口大小
超时
TCP 每发送一个报文段,就对这个报文段设置一次计时器,重传时间到期但还未收到确认时,就要重传这一报文段
由于 TCP 的下层是一个互联网环境,IP 数据报所选择的路由变化很大,因而传输层的往返时延的方差也很大
为了计算超时计时器的重传时间,TCP 采用一种自适应算法,它记录一个报文段的往返时间 RTT
TCP 保留了 RTT 的一个加权平均往返时间 RTTs,它会随新测量 RTT 样本值的变化而变化
超时计时器设置的超时重传时间 RTO 应略大于 RTTs,但也不能大太多,否则 TCP 不能很快重传,导致数据传输时延大
冗余 ACK
超时重传的周期往往太长,因此发送方通过注意冗余 ACK 来较好地检测丢包情况
冗余 ACK:接收方再次发送某个报文段的确认 ACK,而发送方先前已经收到过该报文段的确认了
TCP 规定每当比期望序号大的失序报文段到达时,就发送一个冗余 ACK 指明下一个期待字节的序号
TCP 规定发送方收到对同一个报文段的 3 个冗余 ACK 时,就认为被确认报文段之后的报文段已经丢失
这种技术通常称为快速重传,冗余 ACK 还被用在拥塞控制中,这将在后面的内容中讨论
TCP 流量控制
TCP 提供流量控制服务来消除发送方发送速率太快,从而使接收方缓存区溢出的可能性
TCP 提供一种基于滑动窗口协议的流量控制机制,滑动窗口在数据链路层有介绍
在通信过程中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小来实现流量控制
- 接收窗口 rwnd:
TCP报文段首部中的窗口字段值;通过调整 rwnd,来限制发送方向网络注入报文的速率
发送方总是根据最新收到的 rwnd 值来限制自己发送窗口的大小,从而保证不会使接收方的接受缓冲溢出
如下图,建立连接时确认 rwnd 为 400,期间进行了三次流量控制,最后把窗口减小到 rwnd = 0

TCP 为每一个连接设有一个持续计时器,只要 TCP 连接的一方收到对方的零窗口通知,就启动持续计时器
若持续计时器设置的时间到期,就发送一个零窗口探测报文段,接收方收到探测报文段时给出现在的窗口值
传输层和数据链路层的流量控制的区别是:
- 传输层定义端到端用户之间的流量控制,数据链路层定义两个中间的相邻结点的流量控制
- 数据链路层的滑动窗口协议的窗口大小不能动态变化,传输层的则可以动态变化
TCP 拥塞控制
拥塞控制是指防止过多的数据注入网络,保证网络中的路由器或链路不致过载
出现拥塞时,端点并不了解拥塞发生的细节,对通信连接的端点来说,拥塞往往表现为通信时延的增加
拥塞控制与流量控制的区别:
- 拥塞控制:让网络能够承受现有的网络负荷,是一个全局性的过程,涉及所有与降低网络传输性能有关的所有因素
- 流量控制:对点对点的通信量的控制,是个端到端的问题,它抑制发送端发送数据的速率,以便接收端来得及接收
但拥塞控制和流量控制都通过控制发送方发送数据的速率来达到控制效果
TCP 协议要求发送方维护以下两个窗口:
接收窗口 rwnd:接收方根据目前接收缓存大小来确定的最新窗口值,反映接收方的容量
拥塞窗口 cwnd:发送方根据自己估算的网络拥塞程度而设置的窗口值,反映网络的当前容量
只要网络未出现拥塞,拥塞窗口就再增大一些,以便把更多的分组发送出去
但只要网络出现拥塞,拥塞窗口就减小一些,以减少注入网络的分组数
发送方在确定发送报文段的速率时,既要考虑接收方的接收能力,又要考虑不要使网络发生拥塞
因此发送窗口的上限值应取接收窗口 rwnd 和拥塞窗口 cwnd 中较小的一个,即发送窗口的上限值 = min[rwnd, cwnd]
因特网建议标准定义了进行拥塞控制的 4 种算法:慢开始、拥塞避免、快重传、快恢复;下面介绍发送方如何维护 cwnd
慢开始和拥塞避免
慢开始算法
在 TCP 刚刚连接好并开始发送 TCP 报文段时,先令拥塞窗口 cwnd = 1,即一个最大报文段长度 MSS
每收到一个对新报文段的确认后,将 cwnd 加 1,逐步增大发送方的 cwnd,使分组注入网络的速率更加合理
注意:是收到对新报文段确认才加 1,每次发送的报文段数量翻倍,所以接收到的确认翻倍,即 cwnd 翻倍
慢开始的慢是指在 TCP 开始发送报文段时先设置 cwnd = 1,然后再逐渐增大 cwnd,这对防止网络出现拥塞很有用
每经过一个传输轮次,即往返时延 RTT,cwnd 就会加倍,当 cwnd 达到慢开始门限 ssthresh,就改用拥塞避免算法
注意:这里 cwnd = 1 是方便写法,实际上 cwnd = 1 × MSS
拥塞避免算法
拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,具体做法是:
每经过一个往返时延 RTT 就把 cwnd 加 1,使拥塞窗口 cwnd 按线性规律缓慢增长,这比慢开始的增长速率缓慢得多
根据 cwnd 的大小执行不同的算法,可归纳如下:
- 当 cwnd < ssthresh 时,使用慢开始算法
- 当 cwnd > ssthresh 时,改用拥塞避免算法
- 当 cwnd = ssthresh 时,既可使用拥塞避免算法(通常做法),又可使用慢开始算法
网络拥塞的处理
无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(即出现超时重传)
就要把慢开始门限 ssthresh 设置为出现拥塞时的发送方的 cwnd 值的一半,但不能小于 2
然后把拥塞窗口 cwnd 重新设置为 1,执行慢开始算法
以便迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完
慢开始和拥塞避免算法的实现过程如下图:
初始时,拥塞窗口置为 1,即 cwnd = 1,慢开始门限置为 16,即 ssthresh = 16
慢开始阶段,cwnd 的初值为 1,以后发送方每收到一个确认 ACK,cwnd 加 1
当拥塞窗口 cwnd 增长到慢开始门限 ssthresh 时,就改用拥塞避免算法,cwnd 按线性规律增长
假定 cwnd = 24 时网络出现超时,更新 ssthresh 值为 12,cwnd 重置为 1,执行慢开始算法

注意:在慢开始阶段,若 2cwnd > ssthresh,则下一个 RTT 后的 cwnd 等于 ssthresh,而不等于 2cwnd
在慢开始和拥塞避免算法中使用了乘法减小和加法增大方法:
乘法减小:在慢开始阶段或拥塞避免阶段,出现超时,就把慢开始门限值 ssthresh 设置为当前拥塞窗口的一半
网络频繁出现拥塞时,ssthresh 值就下降得很快,以大大减少注入网络的分组数
加法增大:执行拥塞避免算法后,在收到对所有报文段的确认后,即经过一个 RTT
就把拥塞窗口 cwnd 增加一个 MSS 大小,使拥塞窗口缓慢增大,以防止网络过早出现拥塞
拥塞避免不是指完全避免拥塞,而是指在拥塞避免阶段把拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞
快重传和快恢复
快重传和快恢复算法是对慢开始和拥塞避免算法的改进
快重传
[TCP 可靠传输机制中](#冗余 ACK),快重传技术使用了冗余 ACK 来检测丢包的发生
同样,冗余 ACK 也用于网络拥塞的检测,因为丢包了就意味着网络可能出现了拥塞
快重传并非取消重传计时器,而是在某些情况下可更早地重传丢失的报文段
快恢复
快恢复算法的原理如下:
发送方连续收到三个冗余 ACK 时,执行乘法减小算法,把慢开始门限 ssthresh 设置为此时发送方 cwnd 的一半
并把 cwnd 值设置为慢开始门限 ssthresh 改变后的数值,然后开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大
发送方认为网络很可能没有发生严重拥塞,否则就不会有几个报文段连续到达接收方也不会连续收到重复确认
由于跳过了拥塞窗口 cwnd 从 1 起始的慢开始过程,所以被称为快恢复
快恢复算法的实现过程如下,作为对比,虚线为慢开始的处理过程:

在流量控制中,发送方发送数据的量由接收方决定;在拥塞控制中,则由发送方自己通过检测网络状况来决定
总结:TCP 连接建立和网络出现超时时,采用慢开始和拥塞避免算法;接收到冗余 ACK 时,采用快重传和快恢复算法
