第五章 运输层
5.1 运输层概述
网络层为主机之间提供逻辑服务,而运输层为应用进程之间提供端到端的逻辑服务。
严格地讲,两台主机进行通信就是两台主机中的应用进程互相通信。而 IP 协议只能把分组送到目的主机,还需要借助运输层的协议才能交付主机中的应用进程。 如下图所示,主机 A 的应用进程 AP1、AP2分别和主机的应用进程AP3、AP4 通信。
运输层向应用层屏蔽了下面网络的细节(如网络拓扑、所采用的路由选择协议等),使应用进程看见的就是好像在两个运输层实体之间有一条端到端的逻辑通信信道,但数据的传送实际上是沿着图中的虚线方向(经过多个层次)传送的。
5.1.1 运输层的两个主要协议
运输层有两个主要的协议:用户数据报协议 UDP(User Datagram Protocol) 和传输控制协议 TCP(Transmission Control Protocol)。它们都有复用和分用,以及差错检测的功能。把传输的运输数据单元称为报文段。
UDP 在传送数据之前不需要先建立连接。接收方在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但简单,适用某些应用方向,如视频会议、视频直播等。
TCP 则提供面向连接的服务。在传送数据之前必须先建立连接,数据传送结束后要释放连接。 TCP 不提供广播或多播服务。由于 TCP 的确认、流量控制、计时器以及连接管理等机制,使得报文段的首部较大,还要占用许多的处理机资源。
当运输层采用面向连接的 TCP 协议时,尽管下面的网络是不可靠的,但这种逻辑通信信道相当于一条全双工的可靠信道;当运输层采用无连接的 UDP 协议时,这种逻辑通信信道仍然是一条不可靠信道。
一些应用和应用层协议主要使用的运输层协议 (UDP 或 TCP)如下图所示:
5.1.2 运输层的端口
应用层所有的应用进程都可以通过运输层再传送到 IP 层(网络层),这就是复用。运输层从 IP 层收到数据后,必须分别交付数据指明的各应用进程,这就是分用。显然这需要给每个应用进程赋予不同的标志。
该标志就是在运输层使用的协议端口(protocol port) ,简称为端口(port)。当应用层要发送数据时,应用进程就把数据发送到适合的端口,然后运输层从该端口读取数据,进行后续处理;当运输层收到对方主机发来的数据时,就把数据发送到适当的端口,然后应用进程从该端口读取数据。显然,端口应有一定容量来暂存数据。
请注意,在协议栈层间的抽象的协议端口是软件端口,即是应用层的各种协议进程与运输实体进行层间交互的一种地址,不同的系统具体实现端口的方法是不同的(取决于系统使用的操作系统)。而路由器或交换机上的硬件端口是不同硬件设备进行交互的接口。
运输层用一个 16 位端口号来标志一个端口。端口号只具有本地意义,只是为了标志本计算机应用层中的各个进程在和运输层交互时的层间接口。在互联网的不同计算机中,相同的端口号是没有关联的。
由此可见,不同主机的进程要互相通信,不仅要知道对方的 IP 地址(为了找到对方的计算机),而且还要知道对方的端口号(为了找到对方计算机中的应用进程)。
运输层的端口号分为服务器端使用的端口号 ( 0 ~ 1023 指派给熟知端口,部分如下表示, 1024 ~ 49151 是登记端口号)和客户端暂时使用的端口号 (49152 ~ 65535)
应用程序 | FTP | TELNET | SMTP | DNS | TFTP | HTTP | SNMP | SNMP(trap) | HTTPS |
---|
熟知端口号 | 21 | 23 | 25 | 53 | 69 | 80 | 161 | 162 | 443 |
5.2 用户数据报协议 UDP
用户数据报协议 UDP 主要特点有:
- 无连接的,两个运输层的UDP之间并没有建立连接,简单方便。
- 尽最大努力交付,即不保证可靠交付,发送的报文可能丢失或不按先后顺序到达。
- 面向报文的。一次交付一个完整的报文。UDP 对应用程序交下来的报文,添加首部后就向下交付 IP 层;对 IP 层交上来的 UDP 用户数据报,去除首部后就交付给上层的应用进程。
- 没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。正好适合实时应用的需求,视频会议等。
- 支持一对一、一对多、多对一和多对多的交互通信。
- 首部开销小,只有 8个字节,比 TCP 20 个字节的首部要短。
用户数据报 UDP 有两个字段:数据字段和首部字段。首部字段很简单,只有 8 个字节 (如下图) ,由 4 个字段组成,长度都是 2 个字节。各字段意义如下:
-
源端口 源端口号,在需要对方回信时选用。不需要时可用全 -
目的端口 目的端口号,在终点交付报文时必须使用。 -
长度 UDP 用户数据报的长度,其最小值是 8(仅有首部)。 -
检验和 检测 UDP 用户数据报在传输中是否有错。有错就丢弃。
当运输层从 IP 层收到 UDP 数据报时,就根据首部中的目的端口,把 UDP 数据报通过相应的端口,应用进程在该端口读取数据。如果接收方 UDP 发现收到的报文中的目的端口号不正确(即不存在对应于该端口号的应用进程) ,就丢弃该报文,并由网际控制报文协议 ICMP 发送"端口不可达"差错报文给发送方。
在计算检验和时,先要在 UDP 用户数据报之前先增加 12 个字节的伪首部,如上图所示。这种伪首部既不向下传送也不向上递交,仅仅是为了计算检验和,可当作实际上不存在。计算检验和如下展示:
可以看到UDP 计算检验和的方法和计算 IP 数据报首部检验和的方法相似,但 UDP 的检验和是把首部和数据部分一起都检验。
5.3 传输控制协议TCP概述
5.3.1 TCP 的特点
-
面向连接。应用程序在使用 TCP 协议之前,必须先建立 TCP 连接。传送数据完毕后,必须释放该连接。该TCP连接是一条虚连接(也就是逻辑连接) -
每一条 TCP 连接只能有两个端点(endpoint) ,每一条 TCP 连接只能是点对点的(一 对一)。 -
提供可靠交付的服务。通过 TCP 连接传送的数据,无差错、不丢失、不重复, 并且按序到达。 -
提供全双工通信。 TCP 连接的两端都设有发送缓存和接收缓存,用来临时存放双向通信的数据,允许通信双方的应用进程在任何时候都能发送数据。 在发送时, 应用程序只需把数据传送给 TCP 的缓存,由 TCP 在合适的时候发送数据。在接收时, TCP 把收到的数据放入缓存,上层的应用进程在合适的时候读取缓存中的数据。 -
面向字节流。 虽然应用进程和 TCP 的交互是一次一个数据块(大小不等),但 TCP 把与应用进程交下来的数据仅仅看成是一连串的无结构的字节流(流入到进程或从进程流出的字节序列)来传送。 但接收方进程应能还原并识别字节流。如下展示:
TCP 和 UDP 在发送报文时所采用的方式完全不同。 TCP 根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节 ,而UDP 发送的报文段长度是应用进程给出的。如果应用进程传送到 TCP 缓存的数据块太长, TCP 就把它划分短一些再传送;如果应用进程一次发送的字节数过少, TCP 也可以等待积累到足够的字节后再构成报文段发送出去。
5.3.2 套接字
TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket) 或插口。套接字用 ( IP地址:端口号 )表示,举例如 192.3.4.5: 80 。每一条 TCP 连接唯一地被通信两端的两个端点(即两个套接字)所确定。即TCP 连接::= {socketl, socket2} = {(IP1: portl), (IP2: port2)} 。
用户认为的信息之间传输只是建立以两个应用程序上,实际上在TCP连接中是靠套接字来作为他们连接的桥梁。套接字是应用进程为了获得网络通信服务而与操作系统进行交互的一种机制。如下所示:
5.4 TCP报文段的首部
TCP 虽然是面向字节流的,但 TCP 传送的数据单元却是报文段。一个 TCP 报文段分为首部和数据两部分,而 TCP 的全部功能都体现在它首部中各字段的作用。
TCP 报文段首部的前 20 个字节是固定的(如下图所示),后面有 4n 字节是根据需要而增加的选项 (n 是整数)。
首部固定部分各字段的意义如下:
(1) 源端口和目的端口 各占 2 个字节,分别写入源端口号和目的端口号。TCP 和 UDP的复用与分用功能都是通过端口实现的。
(2) 序号(小写seq) 占 4 字节,在一个 TCP 连接中传送的字节流中的每一个字节都按顺序编号, 首部中的序号字段值则指的是本报文段所发送的数据的第一个字节的序号。 如一报文段的序号字段值是 301,携带的数据共有 100 字节,则下一个报文段的序号应为 401。
(3) 确认号(小写ack) 占 4 字节,是期望收到对方下一个报文段的第一个数据字节的序号。同时,若确认号 = N 则表明:到序号 N - 1 为止的所有数据都己正确收到。
(4) 数据偏移 占 4 位,指出 TCP 报文段的首部长度。
(5) 保留 占6位,保留为今后使用,目前置为0 。
(6) 紧急位 URG (URGent) URG = 1 时,表明紧急指针字段有效。发送应用进程就告诉发送方的 TCP 有紧急数据要传送,于是发送方 TCP 就把紧急数据插入到本报文段数据的最前面,而在紧急数据后面的数据仍是普通数据 。要与首部中紧急指针字段配合使用。
(7) 确认位 ACK (ACKnowledgment) 只当 ACK= 1 时确认号字段才有效。规定在连接建立后所有传送的报文段都必须把 ACK 置 1 。
(8) 推送位 PSH (PuSH) 当发送方 TCP 报文段的 PSH 置1,立刻把该报文段发送出去。接收方 TCP 收到 PSH = 1 的报文段,应立即向上交付给接收应用进程。 推送操作实际很少使用。
(9) 复位位 RST (ReSeT) RST = 1 时,表明 TCP 连接中出现严重差错(如由于主机崩溃或其他原因),必须释放连接,然后再重新建立运输连接。 RST 也可称为重建位或重置位。
(10) 同步位 SYN (SYNchronization) 在连接建立时用来同步序号。SYN 置为 1 就表示这是一个连接请求或连接接受报文。
(11) 终止位 FIN (FINish) 用来释放一个连接。当 FIN= 1 时,表明此报文段的发送方的数据己发送完毕,并要求释放TCP连接。
(12) 窗口 占 2 字节。因为接收方的数据缓存空间是有限的,窗口字段指出了现在允许对方发送的数据量(以字节为单位)。窗口值经常在动态变化着。
(13) 检验和 占 2 字节。检验的范围包括首部和数据这两部分,若收到的分组被检测出有差错,则丢弃。和 UDP 用户数据报一样,在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。格式与UDP 用户数据报的伪首部一样,但第四个字段改为6(TCP的协议号),第五个字段为TCP数据报的长度。
(14) 紧急指针 占 2 字节。仅在 URG = 1 时才有意义,指出本报文段中的紧急数据的字节数。窗口为零时也可发送紧急数据。
(15) 选项 长度可变,最长可达 40 字节。最后的填充字段仅仅是为了整个TCP首部长度是4字节的整数倍。
选项中可以有:
-
最大报文段长度 MSS,指明每一个 TCP 报文段中的数据字段的最大长度。默认为536字节,(576字节的IP数据报 - 20 IPv4首部 - 20 TCP固定首部) -
窗口扩大选项,为了扩大窗口,将窗口位数从16增加到30位。 -
时间戳,用来计算往返时间 RTT 和 防止高速率时的序号绕回。 -
选择确认SACK,当 TCP 的接收方在接收的数据字节流的序号不连续,形成了一些不连续的字节块,如0~1000 ,1500~3000 。每缺一个地址块,需要2个边界,共8个字节。额外还需要 1 个字节指明是 SACK 选项, 1 个字节指明这个选项要占用多少字节。
5.5 可靠传输的工作原理
在理想传输条件(即传输信道不产生差错,不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据)下,不需要采取任何措施就能够实现可靠传输。
但实际的网络一般不具备理想传输条件。但可以使用一些可靠传输协议,当出现差错时让发送方重传出现差错的数据,同时在接收方来不及处理收到的数据时,及时告诉发送方适当降低发送数据的速度。可以使不可靠的传输信道就能够实现可靠传输。
5.5.1 停止等待协议
虽然现在链路层已不需提供可靠的传输,但早期的通信链路不太可靠,链路层是使用可靠的通信协议的,如停止等待协议。
停止等待协议能够在不可靠的传输网络上实现可靠的通信。每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。分组需要进行编号。 可能有以下几种情况:
(1)无差错情况,接收方收到分组后发送确认,发送方收到确认。
(2)出现差错,接收方没接到或不接受发送方发的分组,就不回送确认。发送方只要超过了超时计时器设置的时间仍然没有收到确认,就认为刚才发送的分组丢失了, 因而重传前面发送过的分组,这就是超时重传。
(3)确认丢失和确认迟到,超时重传。若接收方收到重复分组,就丢弃该分组,但同时还要发送确认。
使用上述的这种可靠传输协议常称为自动重传请求 ARQ 。优点是简单,缺点时信道利用率太低。如下所示。信道的利用率U= TD / TD+RTT+TA。
为了提高信道利用率,采用连续 ARQ 协议。
发送方维持一个发送窗口,凡位于发送窗口内的分组都可连续发送出去,而不需要等待对方的确认,如下所示。
接收方采用累积确认, 对按序到达的最后一个分组发送确认,表明到这个分组为止的所有分组都己正确收到了。缺点是不能向发送方反映出接收方已经正确收到的所有分组的信息。如发送方发送了前 5 个分组,而中间的第 3 个分组丢失了。这时接收方只能对前 2 个分组发出确认,发送方只好把后面的 3 个分组再重传一次。叫做回退 N 帧。
5.6 TCP可靠传输的实现
TCP使用的是滑动窗口协议,具备上述连续ARQ的特性。
TCP 的滑动窗口是以字节为单位的。现假定 A 发送了31-41的数据,A 的发送窗口和 B 的接收窗口如下所示:
发送方的发送窗口是根据接收方的接收窗口和网络的拥塞情况来设置的,里面的序号表示允许发送的序号。当收到了新的确认,发送窗口通常向前移动。
接收方的接收窗口受到接收应用进程处理速度影响,由窗口字段值指定大小。通常对不按序到达的数据是先临时存放在接收窗口中,等收到所缺少的字节后,再接序交付上层的应用进程。
实际上,A和B都有发送窗口和接收窗口,且一般为数千字节大小。
已知,发送方的应用进程把字节流写入 TCP 发送缓存,接收方的应用进程从 TCP 的接收缓存中读取字节流,而窗口和缓存的关系如下:
发送缓存暂时存放: TCP 己发送出但尚未收到确认的数据 和 发送方 TCP 准备发送的数据。已被确认的数据应当从发送缓存中删除。发送应用程序必须控制写入缓存的速率,防止发送缓存的空间不足;
接收缓存暂时存放:按序到达但尚未被接收进程读取的数据 和 未按序到达的数据。如果接收应用进程来不及读取收到的数据,接收缓存最终就会被填满,使接收窗口减小到零。反之,若能及时从接收缓存中读取收到的数据,接收窗口就可以增大,但最大不能超过接收缓存的大小。
超时重传时间的选择 TCP 的发送方在规定的时间内没有收到确认就要重传己发送的报文段。但由于互联网环境复杂,报文段传播时间难以确定。为此,TCP采用了自适应的算法来计算超时重传时间 RTO。
超时重传时间 RTO 的计算公式为:RTO = RTTS + 4 * RTTD 。
其中的RTTS为报文段的往返时间 RTT 的加权平均值,又称加权平均往返时间。每当第一次测量到 RTT 样本时, RTTS = RTT 样本值。但以后每测量到一个新的 RTT 样本,就按下边公式重新计算一次 RTTS :
新的 RTTs = (1 - α) * (旧的 RTTS) + α * (新的 RTT 样本),一般 α =0.125
而RTTD为RTT的偏差的加权平均值,与 RTTS 和新的 RTT 样本之差有关。第一次测量时, RTTD = RTT 样本值 / 2。以后的测量中,则使用下式计算加权平均的 RTTD:
新的 RTTD = (1- ?) * (旧的 RTTD) + ? * ( RTTS 一 新的 RTT 样本),一般 ? =0.25
在计算加权平均 RTTS 时,只要报文段重传了,就不采用其往返时间RTT样本。当报文段每重传一次,就把新的超时重传时间 RTO 设置为旧的重传时间的 2 倍。当不再发生报文段的重传时,才根据上面的公式计算超时重传时间。
5.7 TCP 的流量控制
所谓流量控制(flow control) 就是让发送方的发送速率不要太快,要让接收方来得及接收。 TCP利用滑动窗口实现流量控制,如上图所示,设 A 向 B 发送数据。通过上图中右边的注释可帮助理解整个过程。可知接收方进行了三次流量控制,即修改了接收窗口rwnd三次,从而影响发送方的发送窗口。
只要 TCP 连接的一方收到对方的零窗口报文rwnd = 0,就启动持续计时器。若时间到了,就发送一个零窗口探测报文段,对方在确认这个探测报文段时给出了现在的窗口值。可以防止形成死锁局面,如 A 一直等待 B 发送的非零窗口的通知,B 也一直等待 A 发送的数据的。
TCP 的传输效率与发送时机有关。 应用进程把数据传送到 TCP 的发送缓存后,剩下就由 TCP 来处理。TCP 有不同的机制来控制报文段的发送时机。
推送(push)机制,即推送位PSH = 1,发送方的应用进程指明要求应立即发送报文段 ; 计时器机制,时间到了就把当前己有的缓存数据装入报文段(但长度不能超过 MSS) 发送出去。 Nagle 算法机制:若发送进程把数据逐个字节地送到 TCP 的发送缓存,则 TCP 先把第一个数据字节发送出去,把后面到达的数据先缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。还规定,当数据达到发送窗口大小的一半或达到最大报文长度MSS时,就立即发送一个报文段。
滑窗协议存在糊涂窗口综合征,即当发送进程传送数据很慢、或(缓存满了后)接收进程处理接收缓冲区数据很慢,使得应用进程间每次传送的报文段的有效载荷很小,又传输开销(TCP首部+IP首部)固定,使得网络传输效率很低。为此,接收方应等待一段时间,使得接收缓存的空间可以容纳最大报文长度MSS 或者接收缓存已有一半空闲时,再发出确认报文,并向发送方通知当前的窗口大小。
总结就是,在发送方不发送很小的报文段的同时,接收方也不要在缓存刚有了一点空间就急忙通知给发送方,从而提高网络传输效率。
5.8 TCP的拥塞控制
5.8.1 拥塞控制的一般原理
在计算机网络中的链路容量(即带宽)、交换结点中的缓存和处理机等,都是网络的资源。在某段时间,若对网络中某一资源的需求超过了该资源的可用部分,网络的性能就会变坏,即拥塞。出现网络拥塞的条件为 对资源的需求 > 可用资源
拥塞控制就是防止过多的数据注入到网络中,这样可以使网络中的路由器或链路不致过载,以减缓网络的拥塞状态。拥塞控制是一个全局性的过程,涉及到所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。
而流量控制是个端到端的问题(接收端控制发送端),往往是指点对点通信量的控制。流量控制所要做的就是抑制发送端发送数据的速率,目的是使接收端来得及接收。
进行拥塞控制是需要付出代价(额外开销),但拥塞控制可以使吞吐量更高。如下图所示:
从原理上讲,拥塞控制的方案就是使对资源的需求 > 可用资源 不再成立。拥塞控制是个整体的问题,只有所有的部分都平衡了,问题才能解决。可以分为开环控制和闭环控制两种方法。
开环控制就是在设计网络时先将有关发生拥塞的因素考虑周到,力求网络在工作时不产生拥塞。系统运行后,不再改正; 闭环控制是基于反馈环路的概念,监测网络系统以便检测到拥塞在何时、何处发生, 把拥塞发生的信息传送到可采取行动的地方,调整网络系统的运行以解决出现的问题。
5.8.2 TCP 的拥塞控制方法
TCP的拥塞控制是基于窗口的拥塞控制。即发送方维持一个叫做拥塞窗口 cwnd的状态变量,其大小取决于网络的拥塞程度,且动态地在变化。发送方让自己的发送窗口等于拥塞窗口,但不能大于接收方的接收窗口。
TCP 进行拥塞控制的算法有 4 种,即慢开始 、拥塞避免、快重传和快恢复
慢开始算法:开始时或网络拥塞后,应先探测一下网络的负荷情况,即由小到大逐渐增大拥塞窗口数值。发送方先把初始拥塞窗口 cwnd 设置为 2 到 4 个发送方的最大报文段长度(将初始拥塞窗口的长度设为1),然后每收到一个对新报文段的确认(重传的不算在内)就使拥塞窗口cwnd加倍。还需要设置一个慢开始门限 ssthresh 状态变量,当 cwnd > ssthresh ,开始启动拥塞避免算法。
拥塞避免算法:让拥塞窗口 cwnd 缓慢地增大。即每经过一个往返时间 RTT 把发送方的拥塞窗口 cwnd 加1(即加 1 个初始拥塞窗口大小)。"拥塞避免"是把拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。
快重传算法:让发送方尽早确定个别报文段的丢失,应立即进行重传。规定接收方收到单个报文段后(即使是失序的报文段),立即发送确认或重复确认;
快恢复算法:发送方先调整门限值 ssthresh = cwnd / 2 ,再设置拥塞窗口 cwnd = ssthresh,并开始执行拥塞避免算法。发送方只要一连收到 3 个重复确认,如上图所示(共4个确认M2),即没有发生网络拥塞,只是少接收到个别报文段,应立即重发缺少的报文段。并执行快恢复算法。
通过下图可知拥塞控制时的算法使用情况。
TCP 的拥塞控制可以归纳为如下流程图。
路由器的队列通常按照先进先出FIFO 的规则处理到来的分组。当队列己满时再到达的分组将都被丢弃,叫做尾部丢弃策略。 该策略会导致一连串分组的丢失,出现超时重传,可能会使多条 TCP 连接在同一时间都进入到慢开始状态,影响传输效率,称为全局同步
使用主动队列管理 AQM 可减少网络拥塞的发生。在队列长度达到某个值得警惕的数值时 (即当网络有了某些拥塞征兆时),就主动丢弃到达的分组。这样可以提醒了发送方放慢发送的速率,可减缓网络拥塞的程度。
5.9 TCP的运输连接管理
TCP 是面向连接的协议。运输连接是用来传送 TCP 报文的,有三个阶段,连接建立、数据传送和连接释放。运输连接的管理就是使运输连接的建立和释放都能正常地进行。
TCP 连接的建立采用客户服务器方式。主动发起连接建立的应用进程叫做客户(client) 而被动等待连接建立的应用进程叫做服务器(server)
TCP 建立连接采用三报文握手机制(三次握手),客户端发送连接请求,然后服务器确认客户的连接请求,最后客户要对服务器的确认进行确认。
如上图所示,最初两端的 TCP 进程的是处于 CLOSED(关闭) 状态。 B 的 TCP 服务器进程先创建传输控制块TCB ,然后就处于 LISTEN (收听)状态,等待客户的连接请求。
传输控制块 TCB 存储了每一个连接中的一些重要信息,如: TCP 连接表,指向发送和接收缓存的指针,当前的发送和接收序号等。
- A 的 TCP 客户进程也先创建传输控制块 TCB 。当想要建立 TCP 连接时, 向 B 连接请求报文段(首部中的 同步位SYN = 1 ,初始的序号 seq = x )。 SYN 报文段(即 SYN= 1 的报文段)不能携带数据,但要消耗掉一个序号。 TCP 客户进程进入 SYN-SENT (同步己发送)状态。
- B 收到连接请求报文段后,如同意建立连接,则向 A 发送确认报文段(同步位SYN = 1 和 确认位 ACK = 1,确认号ack = x + 1,初始的 序号 seq = y )。这时 TCP 服务器进程进 SYN-RCVD (同步收到)状态。
- TCP 客户进程收到 B 的确认后,发出对 B 的确认报文段( 确认位ACK= 1,确认号ack=y+1 ,序号 seq = x + 1)。 ACK 报文段可以携带数据,若不携带数据则不消耗序号 。这时, TCP 连接己经建立, A 进入 ESTABLISHED (己建立连接)状态。
- B收到 A 的确认后,也进入 ESTABLISHED 状态。
采用三报文握手的办法,可以防止己失效的连接请求报文段在连接释放后才来到,让服务端误认为还要建立连接,引起错误。
TCP 的连接释放采用四报文握手机制(四次挥手)。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后就进入半关闭状态。当另一方也没有数据再发送时, 则发送连接释放通知,对方确认后就完全关闭了 TCP 连接。
-
现在 A 和 B 都处于 ESTABLISHED 状态。A 想要关闭TCP连接,发出连接释放报文段,并停止再发送数据。 连接释放报文段首部的 终止位FIN = 1 ,序号seq = u (由己传送过的数据的序号决定)。这时进入 FIN-WAIT-1 (终止等待 )状态,等待 B 的确认。FIN 报文段即使不携带数据,也消耗掉一个序号。 -
B 收到连接释放报文段后即发出确认(确认位ACK = 1,确认号ack = u + 1,序号seq = v )。然后 B 就进入 CLOSE-WAIT (关闭等待)状态。此时 TCP 连接处于半关闭状态,若 B 发送数据, A 仍要接收,即从 B 到 A 方向的连接并未关闭。 -
A 收到来自 B 的确认后,就进入 FIN-WAIT-2 (终止等待 2) 状态,等待 B 发出的连接释放报文段。 -
若B已没有需要发送的数据,其应用进程就通知 TCP 释放连接。这时 B 发出连接释放报文段,终止位FIN = 1 ,假定的 序号seq = w (在半关闭状态可能又发送了数据 ),重复的 确认号ack = u+1,确认位ACK = 1。这时 B 就进入 LAST-ACK (最后确认)状态,等待 A 的确认。 -
A 在收到 B 的连接释放报文段后,对此发出确认报文段(确认位ACK = 1,确认号 ack = w+1,序号seq=u+1)。然后进入到 TIME-WAIT (时间等待)状态。此时 TCP 连接还没释放。必须经过时间等待计时器设置的时间 2 个最长报文段寿命MSL 后, 才进入到 CLOSED 状态。当 A 撤销相应的传输控制块 TCB 后,就结束了这次的 TCP 连接。
等待 2MSL 的时间,可以重传可能丢失的最后的ACK 报文段,和使新的连接中不会出现旧的连接请求报文(过期)。
-
B 只要收到了 A 发出的确认,就进入 CLOSED 状态。B 在撤销相应的传输控制块 TCB 后,就结束了这次的 TCP 连接。B 结束 TCP 连接的时间要比 A 早一点。
TCP 还设有一个保活计时器。若服务器一段时间没收到数据,就利用一连 10 个探测报文段来检测客户端是否正常连接,若无响应则关闭连接。
TCP 连接的各种状态之间的关系如下图所示。 方框内是 TCP 可能具有的状态。状态之间的箭头表示可能发生的状态变迁,粗实线箭头表示对客户进程的正常变迁,粗虚线箭头表示对服务器进程的正常变迁,细线箭头表示异常变迁。箭头旁边的字,表明引起这种变迁的原因,或表明发生状态变迁后的动作。
本文参考 计算机网络(第8版) / 谢希仁编著. ----北京:电子工业出版社,2021.6
若对你有所帮助,请点个赞,欢迎交流。
|