第五章 运输层
5.0 大纲
大纲 | 谢仁希 | 王道 |
---|---|---|
进程间通信 | 5.1.1 P203 | |
运输层的端口 | 5.1.3 P206 | |
用户数据报协议UDP | 5.2 P208 | |
传输控制协议TCP | 5.3 P210 | |
可靠传输的工作原理 | 5.4 P212 | |
TCP可靠传输的实现 | 5.6 P221 | |
TCP流量控制 | 5.7 P227 | |
TCP拥塞控制机制 | 5.8 P229 | |
TCP连接管理 | 5.9 P238 |
5.1 进程之间的通信
5.1.1 重要概念
- 运输车向它上层的应用层提供服务
- 只有主机才有运输层,路由器等设备只到网络层
- 真正通信的实体是主机中的进程,都是进程之间的通信,而不是主机。
- 一个很重要的功能——复用(multiplexing)和分用(demultiplexing),是指发送方不同的应用进程都可以使用同一个运输层协议传送数据。
- 网络层和运输层之间的明显的区别:网络层为主机之间提供逻辑通信,而运输层为应用进程之间提供端到端的逻辑通信。
- 运输层还要对收到的报文进行差错检测。
- 两种不同的运输协议:面向连接的 TCP 和无连接的 UDP 。
- 运输层提供的是端到端的逻辑通信信道。
- TCP 协议可以提供可靠交付,且是一条全双工的可靠信道。
- “主机A和主机B进行通信”实际上是指:“运行在主机A上的某个程序和运行在主机B上的另一个程序进行通信”。端到端的通信是进程之间的通信。
网络层是为主机之间提供逻辑通信;运输层为应用进程之间提供端到端的逻辑通信。
5.1.2 使用 UDP 和 TCP 协议的各种应用和应用层协议
应用 | 应用层协议 | 运输层协议 |
---|---|---|
名字转换 | DNS | UDP |
文件传送 | TFTP | UDP |
路由选择协议 | RIP | UDP |
IP 地址配置 | DHCP | UDP |
网络管理 | SNMP | UDP |
远程文件服务器 | NFS | UDP |
IP 电话 | 专用协议 | UDP |
流式多媒体通信 | 专用协议 | UDP |
应用 | 应用层协议 | 运输层协议 |
---|---|---|
电子邮件 | SMTP | TCP |
远程终端接入 | TELNET | TCP |
万维网 | HTTP | TCP |
文件传送 | FTP | TCP |
5.2 运输层的端口
5.2.1 重要概念
-
复用和分用
- 复用:应用层所有的应用进程都可以通过传输层再传输到网络层。
- 分用:传输层从网络层收到数据后交付指明的应用进程。
-
屏蔽作用
- 运输层向高层用户屏蔽了下面网络核心的细节,它使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道。
-
端口号 (protocol port number)
-
端口用一个 16 位端口号进行标志,允许有65,535个不同的端口号。
-
端口号只具有本地意义,即端口号只是为了标志本计算机应用层中的各进程。在互联网中,不同计算机的相同端口号是没有联系的。
-
两个计算机中的进程要互相通信,不仅必须知道对方的端口号(为了找到对方计算机中的应用进程)而且还要知道对方的 IP 地址(为了找到对方的计算机)。
-
-
两大类端口
-
服务器端使用的端口号
- 熟知端口,数值一般为 0 ~ 1023。
- 登记端口号,数值为 1024 ~ 49151,为没有熟知端口号的应用程序使用的。使用这个范围的端口号必须在 IANA 登记,以防止重复。
-
客户端使用的端口号
- 又称为短暂端口号,数值为 49152 ~ 65535,留给客户进程选择暂时使用。
- 当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其他客户进程以后使用。
-
-
软件端口与硬件端口
- 两个不同的概念。
- 在协议栈层间的抽象的协议端口是软件端口。
- 路由器或交换机上的端口是硬件端口。
- 硬件端口是不同硬件设备进行交互的接口,而软件端口是应用层的各种协议进程与运输实体进行层间交互的一种地址。
5.3 用户数据报协议 UDP
5.3.1 重要概念
- UDP 只在 IP 的数据报服务之上增加了很少一点的功能:
- 复用和分用的功能
- 差错检测的功能
- UDP 的主要特点
- UDP 是无连接的,发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延。
- UDP 使用尽最大努力交付,即不保证可靠交付,因此主机不需要维持复杂的连接状态表。
- UDP 是面向报文的。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。
- UDP 一次交付一个完整的报文。
- UDP 没有拥塞控制。因此网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的。很适合多媒体通信的要求。
- UDP 支持一对一、一对多、多对一和多对多的交互通信。
- UDP 的首部开销小,只有 8 个字节,比 TCP 的 20 个字节的首部要短。
- 面向报文的 UDP
- 接收方 UDP 对 IP 层交上来的 UDP 用户数据报,在去除首部后就原封不动地交付上层的应用进程,
一次交付一个完整的报文。 - 应用程序必须选择合适大小的报文。
- 若报文太长,UDP 把它交给 IP 层后,IP 层在传送时可能要进行分片,这会降低 IP 层的效率。
- 若报文太短,UDP 把它交给 IP 层后,会使 IP 数据报的首部的相对长度太大,这也降低了
IP 层的效率。
- 接收方 UDP 对 IP 层交上来的 UDP 用户数据报,在去除首部后就原封不动地交付上层的应用进程,
5.3.2 UDP 的首部格式
-
用户数据报 UDP 有两个字段:
- 数据字段和首部字段。
首部字段有 8 个字节,由 4 个字段组成,每个字段都是 2 个字节。
- 数据字段和首部字段。
-
UDP 基于端口的分用
- 当运输层从 IP 层收到 UDP 数据报时,就根据首部中的目的端口,把 UDP 数据报通过相应的端口,上交给最后的终点——应用进程。
请注意,虽然在 UDP 之间的通信要用到端口号,但由于 UDP 的通信是无连接的,因此不需要使用套接字来建立连接。
UDP校验
UDP 的检验和是把首部和数据部分一起都检验。
在发送端:
- 填上伪首部
- 全0填充检验和字段
- 全0填充数据部分(UDP数据报 要看成许多4B的字串接起来)
- 伪首部+首部+数据部分采用二 进制反码求和
- 把和求反码填入检验和字段
- 去掉伪首部,发送
在接收端:
- 填上伪首部
- 伪首部+首部+数据部分采用二进制反码求和
- 结果全为1 则无差错,否则丢 弃数据报/交给应用层附上出差 错的警告。
5.4 传输控制协议 TCP
5.4.1 重要概念
5.4.2 TCP 最主要的特点
-
TCP 是面向连接的运输层协议,在无连接的、不可靠的 IP 网络服务基础之上提供可靠交付的服务。为此,在 IP 的数据报服务基础之上,增加了保证可靠性的一系列措施。
-
每一条 TCP 连接只能有两个端点 (endpoint),每一条 TCP 连接只能是点对点的(一对一)。
-
TCP 提供可靠交付的服务。
-
TCP 提供全双工通信。
-
面向字节流
-
TCP 中的“流”(stream) 指的是流入或流出进程的字节序列。
“面向字节流”的含义是:虽然应用程序和 TCP 的交互是一次一个数据块,但 TCP 把应用程序交下来的数据看成仅仅是一连串无结构的字节流。
-
TCP 面向流的概念:
TCP 不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系。
但接收方应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。
-
-
注意:
-
TCP 连接是一条虚连接而不是一条真正的物理连接。
TCP 对应用进程一次把多长的报文发送到 TCP 的缓存中是不关心的。
TCP 根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP 发送的报文长度是应用进程给出的)。
TCP 可把太长的数据块划分短一些再传送。
TCP 也可等待积累有足够多的字节后再构成报文段发送出去。
-
5.4.3 TCP 的连接
- TCP 把连接作为最基本的抽象。
- 每一条 TCP 连接有两个端点。
- TCP 连接的端点不是主机,不是主机的IP 地址,不是应用进程,也不是运输层的协议端口。
- TCP 连接的端点叫做套接字 (socket) 或插口。
套 接 字 s o c k e t = ( I P 地 址 : 端 口 号 ) 套接字 socket = (IP地址 : 端口号) 套接字socket=(IP地址:端口号) - 端口号拼接到 (contatenated with) IP 地址即构成了套接字。
- 每一条 TCP 连接唯一地被通信两端的两个端点(即两个套接字)所确定。即:
⭐️ TCP 连接 :: = {socket1, socket2}
= {(IP1: port1),(IP2: port2)} - TCP 连接,IP 地址,套接字
- TCP 连接就是由协议软件所提供的一种抽象。
TCP 连接的端点是个很抽象的套接字,即(IP 地址:端口号)。
同一个 IP 地址可以有多个不同的 TCP 连接。
同一个端口号也可以出现在多个不同的 TCP 连接中。
- TCP 连接就是由协议软件所提供的一种抽象。
5.5 可靠传输的工作原理
5.5.0 引言
-
IP 网络所提供的是不可靠的传输
-
理想的传输条件特点:
- 理想的传输条件有以下两个特点:
- 传输信道不产生差错。
- 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据。
- 在这样的理想传输条件下,不需要采取任何措施就能够实现可靠传输。
- 然而实际的网络都不具备以上两个理想条件。必须使用一些可靠传输协议,在不可靠的传输信道实现可靠传输。
- 理想的传输条件有以下两个特点:
5.5.1 停止等待协议
0. 概念
- “停止等待”就是每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。
- 全双工通信的双方既是发送方也是接收方。
- 为了讨论问题的方便,我们仅考虑 A 发送数据,而 B 接收数据并发送确认。因此 A 叫做发送方,而 B 叫做接收方。
1. 要点
- 停止等待。发送方每次只发送一个分组。在收到确认后再发送下一个分组。
- 编号。对发送的每个分组和确认都进行编号。
- 自动重传请求。发送方为每个发送的分组设置一个超时计时器。若超时计时器超时,发送方会自动重传分组。
简单,但信道利用率太低。
2. 几种情况
1)无差错情况
2)出现差错
-
在接收方 B 会出现两种情况:
- B 接收 M1 时检测出了差错,就丢弃 M1,其他什么也不做(不通知 A 收到有差错的分组)。
- M1 在传输过程中丢失了,这时 B 当然什么都不知道,也什么都不做。
-
在这两种情况下,B 都不会发送任何信息。
-
但 A 都必须重发分组,直到B正确接收为止,这样才能实现可靠通信。
-
问题:A 如何知道 B 是否正确收到了 M1 呢?
答:超时重传- A 为每一个已发送的分组都设置了一个超时计时器。
- A 只要在超时计时器到期之前收到了相应的确认,就撤销该超时计时器,继续发送下一个分组 M2 。
- 若A在超时计时器规定时间内没有收到B的确认,就认为分组错误或丢失,就重发该分组。
-
问题:若分组正确到达B,但B回送的确认丢失或延迟了,A未收到B的确认,会超时重发。B 可能会收到重复的 M1 。B如何知道收到了重复的分组,需要丢弃呢?
答:编号- A为每一个发送的分组都进行编号。若B收到了编号相同的分组,则认为收到了重复分组,丢弃重复的分组,并回送确认。
- B为发送的确认也进行编号,指示该确认是对哪一个分组的确认。
- A根据确认及其编号,可以确定它是对哪一个分组的确认,避免重发发送。若为重复的确认,则将其丢弃。
3)确认丢失和确认迟到
- 确认丢失
- 若 B 所发送的对 M1 的确认丢失了,那么 A 在设定的超时重传时间内不能收到确认,但 A 并无法知道:是自己发送的分组出错、丢失了,或者是 B 发送的确认丢失了。因此 A 在超时计时器到期后就要重传 M1
- 假定 B 又收到了重传的分组 M1。这时 B 应采取两个行动:
- 第一,丢弃这个重复的分组 M1,不向上层交付。
- 第二,向 A 发送确认。不能认为已经发送过确认就不再发送,因为 A 之所以重传 M1 就表示 A 没有收到对 M1 的确认。
- 确认迟到
- 传输过程中没有出现差错,但 B 对分组 M1 的确认迟到了。
- A 会收到重复的确认。对重复的确认的处理很简单:收下后就丢弃。
- B 仍然会收到重复的 M1,并且同样要丢弃重复的 M1,并重传确认分组。
- 请注意
在发送完一个分组后,必须暂时保留已发送的分组的副本,以备重发。
分组和确认分组都必须进行编号。
超时计时器的重传时间应当比数据在分组传输的平均往返时间更长一些。
- 自动重传请求 ARQ
- 通常 A 最终总是可以收到对所有发出的分组的确认。如果 A 不断重传分组但总是收不到确认,就说明通信线路太差,不能进行通信。
- 使用上述的确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信。
- 像上述的这种可靠传输协议常称为自动重传请求 ARQ (Automatic Repeat Request)。意思是重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组。
4)信道利用率(低下)
- 停止等待协议的优点是简单,缺点是信道利用率太低。
信 道 利 用 率 U = T D T D + R T T + T A 信道利用率U=\frac{T_{D}}{T_{D}+\mathrm{RTT}+T_{A}} 信道利用率U=TD+RTT+TATD - 可以看出,当往返时间 RTT 远大于分组发送时间 TD 时,信道的利用率就会非常低。
若出现重传,则对传送有用的数据信息来说,信道的利用率就还要降低。
5)流水线传输(解决信道利用率低下)
- 流水线传输就是发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。这样可使信道上一直有数据不间断地传送。
- 由于信道上一直有数据不间断地传送,这种传输方式可获得很高的信道利用率。
5.5.2 连续 ARQ 协议
1)基本思想
- 发送方一次可以发出多个分组。
- 使用滑动窗口协议控制发送方和接收方所能发送和接收的分组的数量和编号。
- 每收到一个确认,发送方就把发送窗口向前滑动。
- 接收方一般采用累积确认的方式。
- 采用回退N(Go-Back-N)方法进行重传。
2)滑动窗口
3)累积确认
- 接收方一般采用累积确认的方式。即不必对收到的分组逐个发送确认,而对按序到达的最后一个分组发送确认,这样就表示:到这个分组为止的所有分组都已正确收到了。
- 优点:容易实现,即使确认丢失也不必重传。
- 缺点:不能向发送方反映出接收方已经正确收到的所有分组的信息。
4)Go-back-N(回退 N)
- 如果发送方发送了前 5 个分组,而中间的第 3 个分组丢失了。这时接收方只能对前两个分组发出确认。发送方无法知道后面三个分组的下落,而只好把后面的三个分组都再重传一次。
- 这就叫做 Go-back-N(回退 N),表示需要再退回来重传已发送过的 N 个分组。
- 可见当通信线路质量不好时,连续 ARQ 协议会带来负面的影响。
5)TCP 可靠通信的具体实现
- TCP 连接的每一端都必须设有两个窗口——一个发送窗口和一个接收窗口。
- TCP 的可靠传输机制用字节的序号进行控制。TCP 所有的确认都是基于序号而不是基于报文段。
- TCP 两端的四个窗口经常处于动态变化之中。
- TCP连接的往返时间 RTT 也不是固定不变的。需要使用特定的算法估算较为合理的重传时间。
5.5.3 滑动窗口协议
1)概念
- 滑动窗口协议比较复杂,是 TCP 协议的精髓所在。
- 发送方维持的发送窗口,它的意义是:位于发送窗口内的分组都可连续发送出去,而不需要等待对方的确认。这样,信道利用率就提高了。
- 连续 ARQ 协议规定,发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置。
2)累积确认
3)滑动窗口协议
4)Go-back-N(回退 N)
5.5.4 比较两种协议(停止等待&ARQ)
连续ARQ协议 | 停止等待协议 | |
---|---|---|
发送的分组数量 | 一次发送多个分组 | 一次发送一个分组 |
传输控制 | 滑动窗口协议 | 停等-等待 |
确认 | 单独确认 + 累积确认 | 单独确认 |
超时定时器 | 每个发送的分组 | 每个发送的分组 |
编号 | 每个发送的分组 | 每个发送的分组 |
重传 | 回退N,多个分组 | 一个分组 |
5.6 TCP 可靠传输的实现
5.6.1 以字节为单位的滑动窗口
0 一些概念
- TCP 使用流水线传输和滑动窗口协议实现高效、可靠的传输。
- TCP 的滑动窗口是以字节为单位的。
- 发送方 A 和接收方 B 分别维持一个发送窗口和一个接收窗口。
- 发送窗口表示:在没有收到确认的情况下,可以连续把窗口内的数据全部发送出去。
- 接收窗口表示:只允许接收落入窗口内的数据。
- 可用窗口表示:允许发送但当前尚未发送的字节数
1 发送流程
发送方
- 发送方 A 根据 接收方 B 构造出自己的发送窗口,发送窗口内的字节在没有收到确认的情况下,可以连续把窗口内的数据全部发送出去。
- 发送窗口的数值一定不能超过 B 的接收窗口数值。
- 已经发送且受到确认的字节退到发送窗口后沿,且不再需要保留。
- 发送窗口的位置由窗口前沿和后沿的位置共同确定。
- 前沿的变化有两种可能:
- 不动(没有收到新的确认)
- 前移(收到了新的确认)
- 前沿不变化有两种可能:
- 没有收到新的确认,对方的通知窗口大小也不变
- 收到了新的确认,但是对方的通知窗口大小缩小了,使得前沿刚好不动
- 前沿的变化有两种可能:
- 描述一个发送窗口的状态需要三个指针:
P3 – P1 = A 的发送窗口(又称为通知窗口)
P2 – P1 = 已发送但尚未收到确认的字节数
P3 – P2 = 允许发送但尚未发送的字节数(又称为可用窗口) - 如果 A 中的发送窗口的序号都用完,但还没有收到确认,必须停止发送,且等到超时之后重传这部分数据。
接收方
- 接收方 B 只对按序号收到的最高序号给出确认。
- 在接受窗口外面,已经发送过确认的数据并且已经交付主机,B 就可以不再保留这些数据。
- B 保留还未上交主机或者还没有按序到达也没有发送过确认的数据。
2 发送缓存与接收缓存的作用
- 发送缓存用来暂时存放:
- 发送应用程序传送给发送方 TCP 准备发送的数据;
- TCP 已发送出但尚未收到确认的数据。
- 接收缓存用来暂时存放:
- 按序到达的、但尚未被接收应用程序读取的数据;
- 不按序到达的数据。
3 强调三点
- A 的发送窗口并不总是和 B 的接收窗口一样大(因为有一定的时间滞后)。
- TCP 标准没有规定对不按序到达的数据应如何处理。通常是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程。
- TCP 要求接收方必须有累积确认的功能,这样可以减小传输开销。
4 接收方发送确认
- 接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。
- 但请注意两点:
第一,接收方不应过分推迟发送确认,否则会导致发送方不必要的重传,这反而浪费了网络的资源。。
第二,捎带确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据。
5.6.2 超时重传时间的选择
0 一些概念
- 重传机制是 TCP 中最重要和最复杂的问题之一。
- TCP 每发送一个报文段,就对这个报文段设置一次计时器。
- 只要计时器设置的重传时间到但还没有收到确认,就要重传这一报文段。
- 重传时间的选择是 TCP 最复杂的问题之一。
1 TCP 超时重传时间设置
- 如果把超时重传时间设置得太短,就会引起很多报文段的不必要的重传,使网络负荷增大。
- 但若把超时重传时间设置得过长,则又使网络的空闲时间增大,降低了传输效率。
- TCP 采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应的确认的时间。这两个时间之差就是报文段的往返时间 RTT。
2 加权平均往返时间
-
TCP保留了RTT的一个加权平均往返时间RTTS(这又称为平滑的往返时间)。
第一次测量到 RTT 样本时,RTTS 值就取为所测量到的 RTT 样本值。以后每测量到一个新的 RTT 样本,就按下式重新计算一次 RTTS:新 的 R T T S = ( 1 − a ) ∗ ( 旧 的 R T T S ) + a ∗ ( 新 的 R T T 样 本 ) 新的RTTS = (1 - a) * (旧的RTTS) + a * (新的RTT样本) 新的RTTS=(1−a)∗(旧的RTTS)+a∗(新的RTT样本)
式中, 0 ≤ a < 1 0≤a<1 0≤a<1。若 a 很接近于零,表示 RTT 值更新较慢。若选择 a 接近于 1,则表示 RTT 值更新较快。
RFC 6298 推荐的 a 值为 1 / 8,即 0.125。
3 超时重传时间 RTO
- RTO (Retransmission Time-Out) 应略大于上面得出的加权平均往返时间 RTTS。
RFC 6298 建议使用下式计算 RTO:
R T O = R T T S + 4 ∗ R T T D RTO = RTTS + 4 * RTTD RTO=RTTS+4∗RTTD - RTTD 是 RTT 的偏差的加权平均值。
RFC 6298 建议这样计算RTTD 。第一次测量时, RTTD 值取为测量到的 RTT 样本值的一半。在以后的测量中,则使用下式计算加权平均的 RTTD :
新 的 R T T D = ( 1 − ß ) ∗ ( 旧 的 R T T D ) + ß ∗ ∣ R T T S − 新 的 R T T 样 本 ∣ 新的 RTTD = (1 - ß ) * (旧的RTTD) + ß * |RTTS - 新的 RTT 样本| 新的RTTD=(1−ß)∗(旧的RTTD)+ß∗∣RTTS−新的RTT样本∣ - ß是个小于 1 的系数,其推荐值是 1/4,即 0.25。
4 Karn 算法
- 在计算平均往返时间 RTT 时,只要报文段重传了,就不采用其往返时间样本。
- 这样得出的加权平均平均往返时间 RTTS 和超时重传时间 RTO 就较准确。
- 但是,这又引起新的问题。当报文段的时延突然增大了很多时,在原来得出的重传时间内,不会收到确认报文段。于是就重传报文段。但根据 Karn 算法,不考虑重传的报文段的往返时间样本。这样,超时重传时间就无法更新。
5 修正的 Karn 算法
- 报文段每重传一次,就把 RTO 增大一些:
新的 RTO = k * (旧的 RTO) - 系数 k 的典型值是 2(典型的做法是取新的重传时间为就的重传时间的2倍)。
- 当不再发生报文段的重传时,才根据报文段的往返时延更新平均往返时延 RTT 和超时重传时间 RTO 的数值。
实践证明,这种策略较为合理。
5.6.3 选择确认 SACK
用于只传送缺少的数据而不重传已经正确到达接收方的数据。
- 如果要使用选择确认,那么在建立 TCP 连接时,就要在 TCP 首部的选项中加上“允许 SACK”的选项,而双方必须都事先商定好。
- 如果使用选择确认,那么原来首部中的“确认号字段”的用法仍然不变。只是以后在 TCP 报文段的首部中都增加了 SACK 选项,以便报告收到的不连续的字节块的边界。
- 由于首部选项的长度最多只有 40 字节,而指明一个边界就要用掉 4 字节,因此在选项中最多只能指明 4 个字节块的边界信息。
5.7 TCP 的流量控制
流量控制:让发送方慢点,要让接收方来得及接收。
5.7.1 利用滑动窗口实现流量控制
- TCP利用滑动窗口机制实现流量控制。
- 在通信过程中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,即接收窗口rwnd (接收方设置确认报文段的窗口字段来将rwnd通知给发送方) ,发送方的发送窗口取接收窗口rwnd和拥塞窗口cwnd的最小值。
1 利用可变窗口进行流量控制举例
2 可能发生死锁
B 向 A 发送了零窗口的报文段后不久,B 的接收缓存又有了一些存储空间。于是 B 向 A 发送了 rwnd = 400 的报文段。
但这个报文段在传送过程中丢失了。A 一直等待收到 B 发送的非零窗口的通知,而 B 也一直等待 A 发送的数据。
如果没有其他措施,这种互相等待的死锁局面将一直延续下去。
3 解决可能发生的死锁问题
- TCP为每一个连接设有一个持续计时器,只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。
- 若持续计时器设置的时间到期, 就发送一个零窗口探测报文段。 接收方收到探测报文段时给出现在的窗口值。
- 若窗口仍然是0,那么发送方就重新设置持续计时器。
5.7.2 TCP 的传输效率
1 一些用来控制 TCP 报文段的发送时机的机制
- 可以用不同的机制来控制 TCP 报文段的发送时机:
第一种机制: TCP 维持一个变量,它等于最大报文段长度 MSS。只要缓存中存放的数据达到 MSS 字节时, 就组装成一个 TCP 报文段发送出去。
第二种机制:由发送方的应用进程指明要求发送报文段,即 TCP 支持的推送 (push) 操作。
第三种机制:发送方的一个计时器期限到了,这时就把当前已有的缓存数据装入报文段发送出去。
(但报文段长度不能超过 MSS) - 如何控制 TCP 发送报文段的时机仍然是一个较为复杂的问题。
2 发送方 糊涂窗口综合症
-
每次仅发送一个字节或很少几个字节的数据时,有效数据传输效率变得很低的现象。
-
发送方 TCP 每次接收到一字节的数据后就发送。
这样,发送一个字节需要形成 41 字节长的 IP 数据报。效率很低。
解决方法:使用 Nagle 算法。
例如:
3 接收方 糊涂窗口综合症
现象:
当接收方的 TCP 缓冲区已满,接收方会向发送方发送窗口大小为 0 的报文。
若此时接收方的应用进程以交互方式每次只读取一个字节,于是接收方又发送窗口大小为一个字节的更新报文,发送方应邀发送一个字节的数据(发送的 IP 数据报是 41 字节长),于是接收窗口又满了,如此循环往复。
原因:
接收方应用进程消耗数据太慢,例如:每次只读取一个字节。
解决方法:
1. <font color='\#1777ff'>让接收方等待一段时间</font>,使得或者接收缓存已有足够空间容纳一个最长的报文段;
2. <font color='\#1777ff'>或者等到接收缓存已有一半空闲的空间</font>。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。
这样就可以使发送方不发送很小的报文段的同时,接收方也不要在缓存刚刚有了一点小的空间就急忙把这个很小的窗口大小信息通知给发送方。
5.7.3 拥塞控制与流量控制的区别
拥塞控制 | 流量控制 |
---|---|
防止过多的数据注入到网络中,使网络中的路由器或链路不致过载; | 抑制发送端发送数据的速率,以使接收端来得及接收; |
是一个全局性的过程,涉及到与降低网络传输性能有关的所有因素。 | 是点对点通信量的控制,是端到端的问题; |
5.8 TCP 的拥塞控制
所谓拥塞(s)控制就是防止过多的数据注入到网络中,这样可以使得网络中的路由器或链路不致过载。
5.8.1 拥塞控制的一般原理
1 一些概念:
- 网络的资源:链路容量(即带宽)、交换结点中的缓存和处理机等。
- 拥塞:在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种现象称为拥塞 (congestion)。
- 拥塞的最坏结果:系统崩溃。
- 拥塞常常趋于恶化。
- 进行拥塞控制需要付出代价。
- 拥塞控制的一般原理
- 拥塞控制的前提是:网络能够承受现有的网络负荷。
实践证明,拥塞控制是很难设计的,因为它是一个动态问题。
分组的丢失是网络发生拥塞的征兆而不是原因。
在许多情况下,甚至正是拥塞控制本身成为引起网络性能恶化、甚至发生死锁的原因。
- 拥塞控制的前提是:网络能够承受现有的网络负荷。
- 拥塞(se)控制就是防止过多的数据注入到网络中,这样可以使得网络中的路由器或链路不致过载。
- 拥塞控制是一个全局性的过程。
- 拥塞控制方法
- 开环控制
- 在设计网络时,事先考虑周全,力求工作时不发生拥塞;
- 思路:力争避免发生拥塞。
- 闭环控制
- 根据网络当前的运行状态采取相应控制措施;
- 思路:在发生拥塞后,采取措施进行控制,消除拥塞。
- 属于闭环控制的有以下几种措施:
(1) 监测网络系统,以便检测到拥塞在何时、何处发生。
(2) 将拥塞发生的信息传送到可采取行动的地方。
(3) 调整网络系统的运行以解决出现的问题。
- 开环控制
- 一些用来监测网络拥塞的方法
- 主要指标有:
1)由于缺少缓存空间而被丢弃的分组的百分数;
2)平均队列长度;
3)超时重传的分组数;
4)平均分组时延;
5)分组时延的标准差,等等。 - 上述这些指标的上升都标志着拥塞的增长。
- 主要指标有:
- 采取行动的时机
- 过于频繁,会使系统产生不稳定的振荡;
- 过于迟缓地采取行动又不具有任何实用价值。
- 解决拥塞的两条思路
- 增加网络可用资源;
- 减少用户对资源的需求。
- TCP 拥塞控制算法(四种)
- 慢开始
- 拥塞避免
- 快重传
- 快恢复
- 接收窗口:接收方根据接受缓存设置的值,并告知给发送方,反映接收方容量。
- 发送窗口 = M i n { 接 收 窗 口 r w n d , 拥 塞 窗 口 c w n d } =Min\{接收窗口rwnd,拥塞窗口cwnd\} =Min{接收窗口rwnd,拥塞窗口cwnd}
- 拥塞窗口:发送方根据自己估算的网络拥塞程度而设置的窗口值,反映网络当前容量。
- 传递拥塞通知方式:
- 发送通知拥塞发生的分组;
- 在分组中保留表示拥塞状态的字段;
- 周期性地发出探测分组等。
2 拥塞产生的原因
-
网络拥塞往往是由许多因素引起的。例如:
- 点缓存的容量太小;
- 链路的容量不足;
- 处理机处理的速率太慢;
- 拥塞本身会进一步加剧拥塞;
-
出现拥塞的原因:
∑ 对资源需求 > 可用资源
3 解决拥塞的方法
首先,增加资源不能解决拥塞,反而可能会使拥塞加剧。
5.8.2 TCP 的拥塞控制方法
1 一些概念
- TCP 采用基于窗口的方法进行拥塞控制。该方法属于闭环控制方法。
- TCP发送方维持一个拥塞窗口 cwnd (Congestion Window)
- 发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量。
- 发送窗口大小不仅取决于接收方窗口,还取决于网络的拥塞状况,
所以真正的发送窗口值为:
真 正 的 发 送 窗 口 值 = M i n ( 接 收 方 窗 口 值 , 拥 塞 窗 口 值 ) 真正的发送窗口值 = Min (接收方窗口值,拥塞窗口值) 真正的发送窗口值=Min(接收方窗口值,拥塞窗口值)
2 控制拥塞窗口的原则
- 只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,这样就可以提高网络的利用率。
- 但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小一些,以减少注入到网络中的分组数,以便缓解网络出现的拥塞。
3 拥塞的判断
- 重传定时器超时
- 网络已经发生了拥塞。
- 收到三个重复的 ACK
- 预示网络可能会出现拥塞(实际可能还未发生拥塞)。
- 进行快重传。
4 四种拥塞控制算法( RFC 5681)
慢开始 (slow-start)
- 目的:用来确定网络的负载能力或拥塞程度。
- 算法的思路:由小到大逐渐增大拥塞窗口数值。
- 两个变量
- 拥塞窗口
- 初始拥塞窗口值:2 种设置方法。
1 至 2 个最大报文段 (SMSS) (旧标准)
2 至 4 个最大报文段 (SMSS) (RFC 5681)✅ - 窗口值逐渐增大。
- 初始拥塞窗口值:2 种设置方法。
- 慢开始门限
- 是为了防止拥塞窗口增长过大引起网络拥塞。
- 拥塞窗口
- 规定:
- 在每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个 SMSS 的数值。
即:拥塞窗口 cwnd 每次的增加量 = min (N, SMSS)
- 在每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个 SMSS 的数值。
- 窗口大小按指数增加,不慢!
- 传输轮次
- 使用慢开始算法后,每经过一个传输轮次 (transmission round),拥塞窗口 cwnd 就加倍。
- 一个传输轮次所经历的时间其实就是往返时间 RTT。
- “传输轮次”更加强调:把拥塞窗口 cwnd 所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个字节的确认。
- 例如,拥塞窗口 cwnd = 4,这时的往返时间 RTT 就是发送方连续发送 4 个报文段,并收到这 4 个报文段的确认,总共经历的时间。
- 设置慢开始门限状态变量 ssthresh
- 慢开始门限 ssthresh 的用法如下:
- 当 cwnd < ssthresh 时,使用慢开始算法。
- 当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。
- 当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞避免算法。
- 慢开始门限 ssthresh 的用法如下:
拥塞避免 (congestion avoidance)
- 思路:让拥塞窗口 cwnd 缓慢地增大,避免出现拥塞。
- 每经过一个传输轮次,拥塞窗口 ++ 。
- 使拥塞窗口 cwnd 按线性规律缓慢增长。
- 在拥塞避免阶段,具有 “加法增大” (Additive Increase) 的特点。
- 当网络出现拥塞时
- 无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(重传定时器超时):
ssthresh = max (cwnd/2,2)
cwnd = 1
执行慢开始算法 - 目的:迅速减少主机发送到网络中的分组数,使得发生拥塞的路由器有足够时间把队列中积压的分组处理完毕。
- 无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(重传定时器超时):
- 在执行慢开始算法时,拥塞窗口 cwnd=1,发送第一个报文段。
- 发送方每收到一个对新报文段的确认 ACK,就把拥塞窗口值加 1,然后开始下一轮的传输(请注意,横坐标是传输轮次,不是时间)。因此拥塞窗口 cwnd 随着传输轮次按指数规律增长。
- 当拥塞窗口 cwnd 增长到慢开始门限值 ssthresh 时(图中的点1 ,此时拥塞窗口 cwnd = 16),就改为执行拥塞避免算法,拥塞窗口按线性规律增长。
- 此处强调一下!!!
“拥塞避免”并非指完全能够避免了拥塞。利用以上的措施要完全避免网络拥塞还是不可能的。
“拥塞避免”是说在拥塞避免阶段把拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。 - 当拥塞窗口 cwnd = 24 时,网络出现了超时(图中的点2 ),发送方判断为网络拥塞。于是调整门限值 ssthresh = cwnd / 2 = 12,同时设置拥塞窗口 cwnd = 1,进入慢开始阶段(第二次)。
- 按照慢开始算法,发送方每收到一个对新报文段的确认 ACK,就把拥塞窗口值加 1。
当拥塞窗口 cwnd = ssthresh = 12 时(图中的点3 ,这是新的 ssthresh 值),改为执行拥塞避免算法,拥塞窗口按线性规律增大。 - 当拥塞窗口 cwnd = 16 时(图中的点4 ),出现了一个新的情况,就是发送方一连收到 3 个对同一个报文段的重复确认(图中记为 3-ACK)。发送方改为执行快重传和快恢复算法。
快重传 (fast retransmit)
- 发送方只要一连收到三个重复确认,就知道接收方确实没有收到报文段,因而应当立即进行重传(即“快重传”),这样就不会出现超时,发送方也不就会误认为出现了网络拥塞。
- 使用快重传可以使整个网络的吞吐量提高约20%。
不难看出,快重传并非取消重传计时器,而是在某些情况下可以更早地(更快地)重传丢失的报文段。
- 采用 快重传 FR (Fast Retransmission) 算法可以让发送方尽早知道发生了个别报文段的丢失。
- 快重传 算法首先要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。
快恢复 (fast recovery)
- 当发送端收到连续三个重复的确认时,由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法,而是执行快恢复算法 FR (Fast Recovery) 算法:
- 慢开始门限 ssthresh = 当前拥塞窗口 cwnd / 2 ;
- 新拥塞窗口 cwnd = 慢开始门限 ssthresh ;
- 开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大。
- 加法增大,乘法减小 (AIMD)
- 可以看出,在拥塞避免阶段,拥塞窗口是按照线性规律增大的。这常称为“加法增大” AI (Additive Increase)。
- 当出现超时或3个重复的确认时,就要把门限值设置为当前拥塞窗口值的一半,并大大减小拥塞窗口的数值。这常称为“乘法减小”MD (Multiplicative Decrease)。
- 二者合在一起就是所谓的 AIMD 算法。
5.8.3 主动队列管理 AQM
TCP 拥塞控制和网络层采取的策略有密切联系。
- 若路由器对某些分组的处理时间特别长,那么这就可能使这些分组中的TCP报文段经过很长时间才能到达终点,结果引起发送方超时,对这些报文段进行重传。
- 重传会使 TCP 连接的发送端认为在网络中发生了拥塞,但实际上网络并没有发生拥塞。
- 对 TCP 拥塞控制影响最大的就是路由器的分组丢弃策略。
1 “先进先出”FIFO 处理规则
-
路由器的队列通常都是按照“先进先出”FIFO (First In First Out) 的规则处理到来的分组。
-
当队列已满时,以后再到达的 所 有 分 组 1 所有分组^1 所有分组1将都被丢弃,所有到达的分组都被丢弃,不论它们属于哪个TCP连接。这就叫做尾部丢弃策略 (tail-drop policy)。
这就会引起全局同步,让所有人都会在同一时间突然都进入慢开始状态,这样链路的吞吐量就会下降。
1 ^1 1(如果能够继续排队,这些分组都将排在队列的尾部)
- 路由器的尾部丢弃往往会导致一连串分组的丢失,这就使发送方出现超时重传,使 TCP 进入拥塞控制的慢开始状态,结果使 TCP 连接的发送方突然把数据的发送速率降低到很小的数值。
2 全局同步
- 更为严重的是,在网络中通常有很多的 TCP 连接,这些连接中的报文段通常是复用在网络层的 IP 数据报中传送的。
- 在这种情况下,若发生了路由器中的尾部丢弃,就可能会同时影响到很多条 TCP 连接,结果使这许多 TCP 连接在同一时间突然都进入到慢开始状态。这在 TCP 的术语中称为全局同步 (global syncronization)。
- 全局同步使得全网的通信量突然下降了很多,而在网络恢复正常后,其通信量又突然增大很多。
3 主动队列管理 AQM
所谓“主动”就是不要等到路由器的队列长度已经达到最大值时才不得不丢弃后面到达的分组,而是在队列长度达到某个值得警惕的数值时(即当网络拥塞有了某些拥塞征兆时),就主动丢弃到达的分组。
4 随机早期检测 RED (不推荐使用)
- 多年的实践证明,RED 的使用效果并不太理想。
- 2015 年公布的 RFC 7567 已经把 RFC 2309 列为“陈旧的”,并且不再推荐使用 RED。
- 对路由器进行主动队列管理 AQM 仍是必要的。
- AQM 实际上就是对路由器中的分组排队进行智能管理,而不是简单地把队列的尾部丢弃。
- 现在已经有几种不同的算法来代替旧的 RED,但都还在实验阶段。
5.8.4 拥塞控制与流量控制的区别
拥塞控制 | 流量控制 |
---|---|
防止过多的数据注入到网络中,使网络中的路由器或链路不致过载; | 抑制发送端发送数据的速率,以使接收端来得及接收; |
是一个全局性的过程,涉及到与降低网络传输性能有关的所有因素。 | 是点对点通信量的控制,是端到端的问题; |
5.8.5 TCP拥塞控制流程图
5.9 TCP 的运输连接管理
5.9.0 概述
1 三个阶段
- TCP 是面向连接的协议。
- TCP 连接有三个阶段:
- 连接建立
- 数据传送
- 连接释放
- TCP 连接的管理就是使 TCP 连接的建立和释放都能正常地进行。
2 客户——服务器方式
- TCP 连接的建立采用客户服务器方式。
- 主动发起连接建立的应用进程叫做客户 (client)。
- 被动等待连接建立的应用进程叫做服务器 (server)。
5.9.1 TCP 的连接建立
0 一些概念
- TCP 建立连接的过程叫做握手。
- 握手需要在客户和服务器之间交换三个 TCP 报文段。称之为三报文握手。
- 采用三报文握手主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。
1 建立连接的过程
- B 的 TCP 服务器进程先创建传输控制块TCB,
准备接受客户进程的连接请求。 - A 的 TCP 向 B 发出连接请求报文段(①客户端发出请求)
- 设置
- 首部的同步位 SYN = 1,ACK = 0(默认)
- 选择序号 seq = x,表明传送数据时候的第一个数据字节序号是 x。
- 规定SYN报文不能携带数据,且要消耗一个序号。
- 设置
- B 的 TCP 收到连接请求报文段后,如同意,则发回确认。(②服务器给出确认)
B 在确认报文段中- 设置
- SYN = 1,ACK = 1,
- 确认号 ack = x + 1,自己选择的序号 seq = y。
- 规定SYN报文不能携带数据,且要消耗一个序号。
- 设置
- A 收到此报文段后向 B 给出确认,(③客户端发出请求的请求,并且通知上层:TCP 连接已经建立)
- 设置
- SYN = 0(默认),ACK = 1,
- 确认号 ack = y + 1。
- 规定ACK报文可以携带数据,如果不携带就不消耗序号。
- A 的 TCP 通知上层应用进程,TCP 连接已经建立。
- 设置
- B 的 TCP 收到主机 A 的确认后,也通知其上层应用进程:TCP 连接已经建立。
- 之后就是无聊的双方全双工通信交流了。
注:为什么 A 最后还要发送一次确认呢?
答:主要是为了防止已失效的连接请求报文段突然又传送到了,因而产生错误。
比如说,由于一些网络或者其他问题 A 发了两次请求连接,其中一次是多发的,如果规定 A 不用确认 B 的确认,那么就会导致即使没有收到确认, B 也误以为连接建立,而浪费资源。
5.9.2 TCP 的连接释放
0 一些概念
- TCP 连接释放过程比较复杂。
- 数据传输结束后,通信的双方都可释放连接。
- TCP 连接释放过程是四报文握手。
1 释放连接过程
- 数据传输结束后,通信的双方都可释放连接。
现在 A 的应用进程先向其 TCP 发出连接释放报文段,并停止再发送数据,主动关闭 TCP 连接。
A 把连接释放报文段首部- 设置
- FIN = 1,序号seq = u,
- 等待 B 的确认。
- 设置
- B 发出确认,确认号 ack = u+1,而这个报文段自己的**序号 seq = v**。(B没说完话,A得等B说完,但不必确认)
TCP 服务器进程通知高层应用进程。
从 A 到 B 这个方向的连接就释放了,TCP 连接处于半关闭状态。B 若发送数据,A 仍要接收。 - 若 B 已经没有要向 A 发送的数据,
其应用进程就通知 TCP 释放连接。 - A 收到**B 的连接释放报文段**后,必须发出确认。
在确认报文段中 - 设置
- ACK = 1,
- 确认号 ack = w + 1,自己的序号 seq = u + 1。
注:A 必须等待 2 M S L 2MSL 2MSL 的时间
第一,为了保证 A 发送的最后一个 ACK 报文段能够到达 B。
第二,防止 “已失效的连接请求报文段”出现在本连接中。
3 其他
- 保活计时器
- 用来防止在TCP连接出现长时期的空闲。
- 保活计时器 通常设置为2小时 。若服务器过了2小时还没有收到客户的信息,它就发送探测报文段。若发送了10个探测报文段(每一个相隔75秒)还没有响应,就假定客户出了故障,因而就终止该连接。
5.9.3 TCP 的有限状态机
为了更清晰地看出 TCP 连接的各种状态之间的关系,特给出下图。
注:
- 箭头旁边的字,表明引起这种变迁的原因,或表明发生状态变迁后又出现什么动作。
- 图中有三种不同的箭头。
- 粗实线箭头表示对客户进程的正常变迁。
- 粗虚线箭头表示对服务器进程的正常变迁。
- 细线箭头表示异常变迁。