计算机网络「五」 运输层

前言:本文为计算机网络系列第五章笔记,陆续会更新余下内容。文章参了:计算机网络微课堂《王道考研计算机网络考研复习指导》《计算机网络( 第7版 )》—— 谢希仁 。本文仅供学习使用,若有侵权联系删除。

系列文章:

计算机网络「一」计算机网络概述

计算机网络「二」物理层

计算机网络「三」 数据链路层

计算机网络「四」 网络层
 

一、运输层概述


之前所介绍的计算机网络体系结构中的物理层、数据链路层以及网络层,它们共同解决了将主机通过异构网络互联起来所面临的问题,实现了主机到主机的通信

但实际上在计算机网络中进行 通信的真正实体是位于通信两端主机中的进程

如何为运行在不同主机上的应用进程提供直接的通信服务 是运输层的任务,运输层协议又称为 端到端 协议,所谓端到端也就是进程到进程。

在这里插入图片描述

从计算机网络体系结构的角度来看运输层

假设 AP1 与 AP4 之间进行基于网络的通信,AP2 与 AP3 之间进行基于网络的通信。在运输层采用不同端口对应不同进程,然后通过网络层及其下层来传输应用层报文。

接收方的运输层通过不同的端口,将收到的应用层报文交付给应用层中相应的应用进程。如图所示
在这里插入图片描述
可以简单地认为,运输层直接为应用进程间的逻辑通信提供服务。“ 逻辑通信 ” 的意思为运输层间的通信好像是沿水平方向传送数据,但事实上并没有一条水平上的物理连接。

运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),它使应用进程看起来就好像 在两个运输层实体之间有一条端到端的逻辑通信信道

根据应用需求的不同,因特网的运输层为应用层提供了两种不同的运输协议,即 面向连接的TCP无连接的UDP,这两种协议就是本章要讨论的主要内容。
 

二、端口号、复用与分用、套接字


我们知道,运行在计算机上的进程使用 进程标识符 PID 来标志。而因特网上的计算机并不是使用统一的操作系统,不同的操作系统(windows、Linux、Mac OS)又使用 不同格式的进程标识符

为了使运行不同操作系统的计算机的应用进程之间能够进行网络通信,就必须 使用统一的方法对 TCP/IP 体系的应用进程进行标识

TCP/IP 体系的运输层使用 端口号 来区分应用层的不同应用进程。

端口号

应用进程通过端口号进行标识。端口号只具有本地意义,即端口号只是为了 标识本计算机应用层中的各进程,在因特网中,不同计算机中的相同端口号是没有联系的 。端口号在运输层的作用相当于 IP 地址 在网络层的作用,或者是 MAC 地址 在数据链路层的作用,只不过 IP 地址和 MAC 地址标识的是主机,而端口标识的是主机中的应用进程。

端口号使用 16 比特表示,取值范围 0 ~ 65535

  1. 熟知端口号:0 ~ 1023,IANA 把这些端口号指派给了 TCP/IP 体系中最重要的一些应用协议。如 FTP: 21/20、HTTP: 80、DNS: 53
  2. 登记端口号:1024 ~ 49151。它是供没有熟知端口号的应用程序使用的,使用这类端口号必须在 IANA 登记,以防重复。
  3. 短暂端口号:49152 ~ 65535,留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其他客户进程以后使用。

发送方的复用和接收方的分用

复用和分用概念

  1. 复用:复用是指发送方不同的应用进程都可使用同一个传输层协议传送数据;
  2. 分用:分用是指接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程。

在这里插入图片描述
补充说明:网络层也有分用和复用:复用是指发送方不同协议的数据都可以封装成 IP 数据报发送出去;分用是指接收方的网络层在剥去首部后把数据交付给相应的协议。

具体说明复用和分用的过程

发送方

  1. 发送方的某些应用进程所发送的不同应用报文,在运输层使用 UDP 协议封装,称为 UDP 复用;在 运输层使用 TCP 协议封装,称为 TCP 复用
  2. 运输层采用端口号来区分不同的应用进程。
  3. 不管是运输层 UDP 协议封装成的 UDP 用户数据报,还是使用 TCP 协议封装成的 TCP 报文段,在网络层都需要使用 IP 协议封装成 IP 数据报,这称为 IP 复用
  4. IP 数据报首部中 协议字段的值 用来表明 IP 数据报的数据载荷部分封装的是何种协议数据单元,如下图:
    在这里插入图片描述

接收方

  1. 接收方的网络层收到 IP 数据报后进行 IP 分用。若协议字段为 17,则将用户数据报上交给运输层的 UDP;若协议字段为 6,则上交给运输层的 TCP。
  2. 运输层对 UDP 用户数据报进行 UDP 分用,对 TCP 报文段进行 TCP 分用。也就是根据端口号,将其交付给上层相应的应用进程。

一些常用的熟知端口号

下图所示为 TCP/IP 体系的应用层常用协议,及它们所使用的运输层熟知端口号:
在这里插入图片描述

不管在运输层使用 UDP 协议还是 TCP 协议,在网络层都需要使用 IP 协议。IP 数据报首部中协议字段 的值,表明了 IP 数据报数据载荷部分封装的是何种协议数据单元。

运输层端口号的应用

如下图,用户 PC、DNS 服务器、Web 服务器通过交换机进行互联,处于同一以太网中。
在这里插入图片描述

DNS(Domain Name Server,域名服务器)是进行域名 (domain name)和与之相对应的IP地址 (IP address)转换的服务器。DNS 中保存了一张域名和与之相对应的 IP 地址的表,以 解析消息的域名

Web 服务器 一般指网站服务器,是指驻留于因特网上某种类型计算机的程序,可以处理浏览器等 Web 客户端的请求并返回相应响应,也可以放置网站文件,让全世界浏览;同时还可以放置数据文件,让全世界下载。

我们在用户 PC 中使用网页浏览器来访问 Web 服务器的内容。在网页浏览器的地址栏中输入 Web 服务器的域名,用户 PC 中的 DNS 客户端 进程会发送一个 DNS 查询请求报文。该报文使用 UDP 协议封装成 UDP 用户数据报,之后将其封装在 IP 数据报中发送给 DNS 服务器。
在这里插入图片描述
DNS 服务器收到后,从中解封出 UDP 用户数据报。因为端口号 53 (DNS 应用程序端口号为 53),所以将数据报的数据载荷部分(查询请求报文)交付给本服务器中的 DNS 服务器端进程。该进程解析查询请求报文的内容后,给用户 PC 发送 DNS 响应报文。之后,通过系列封装成为 IP 数据报,通过以太网发送给用户 PC。
在这里插入图片描述
用户 PC 收到后,解封出 UDP 用户数据报,根据端口号,将其交付给 PC 中 DNS 客户端进程。该进程解析 DNS 响应报文的内容,得到之前请求域名所对应的 IP 地址为 192.168.0.3 。

于是,用户 PC 中的 HTTP 客户端进程 可以向 Web 服务器发送 HTTP 请求报文了。该报文需要 TCP 协议封装为 TCP 报文段,之后封装在 IP 数据报中由以太网传输。
在这里插入图片描述
Web 服务器收到该数据包后解封出 TCP 报文段,根据其首部中目的端口号为 80,因此将 HTTP 请求报文交给本服务器中的 HTTP 服务器端进程 。该进程解析报文查找内容后,给用户 PC 发送 HTTP 响应报文。
在这里插入图片描述
用户 PC 收到并解封,将 HTTP 响应报文交付给用户 PC 中的 HTTP 客户端进程。该进程解析 HTTP 响应报文内容,并在网页浏览器中进行显示。这样,我们就可以成功地从网页中看到 Web 服务器提供的首页内容。

通过上面这个案例的过程分析,你就可以清楚地了解到端口号的妙用,它为主机中各种应用进程作标识,使得各种请求和响应能够有条不紊的进行。

套接字

在网络中通过 IP 地址来标识和区别不同的主机,通过端口号来标识和区分一台主机中的不同应用进程,端口号拼接到 IP 地址 即构成 套接字 Socket

在网络中采用发送方和接收方的套接字来识别端点。

	套接字 Socket = (IP 地址: 端口号)

三、UDP 和 TCP


TCP/IP 协议族在运输层中使用了两个传输协议:

  • 无连接的用户数据报协议 UDP

    无连接服务是指两个实体之间的通信不需要先建立好连接,需要通信时,直接将信息发送到 “ 网络 ” 中,让该信息的传递在网上尽力而为地传送到目的地。

  • 面向连接的传输控制协议 TCP

    面向连接就是在通信双方通信前,必须先建立连接,整个连接的情况一直被实时地监控和管理。通信结束后,应该释放这个连接。

UDP协议

UDP 协议只在 IP 的数据报服务上增加了两个最基本的服务:复用和分用差错检测

UDP 协议有如下优点:

  1. UDP 无需建立连接。 不会引入建立连接的时延。
  2. 无连接状态。不需要维护连接状态,无需跟踪如拥塞控制和确认号等参数。
  3. 分组首部开销小。TCP 有 20B 的首部开销,UDP 仅有 8B 的开销。
  4. 应用层能够好地控制发送的数据和发送的时间。
  5. 支持一对一、一对多、多对一和多对多通信。

UDP 常用于一次性传输较少数据的网络应用,如 DNS、SNMP 等。

UDP 不保证可靠交付,但不意味着应用对数据的要求是不可靠的,所有维护可靠性的工作可以由用户在应用层 来完成。

UDP 是面向报文的。发送方 UDP 对应用层交下来的报文,在添加首部后就向下交付给 IP 层,一次发送一个报文,不合并也不拆分

UDP 可以对数据报做包括数据段在内的差错检测( IP 只对其首部做差错检测)。

TCP 协议

TCP 是在不可靠的 IP 层之上实现的可靠的数据传输协议,它主要解决传输的可靠、有序、无丢失和不重复问题。

TCP 主要有以下特点:

  1. TCP 是面向连接的运输层协议。
  2. 每条 TCP 连接只能有两个端点。
  3. TCP 提供可靠的交付服务。
  4. TCP 提供全双工通信。允许通信双方的应用进程在任何时候都能发送数据,为此 TCP 连接的两端都设有发送缓存和接收缓存,用于存放临时数据。
  5. TCP 是面向字节流的。TCP 把应用程序交付的数据仅视为一连串无结构的字节流。

下面从几个方面对 UDPTCP 进行比较说明

数据传输

  • 使用 UDP 协议的通信双方,可以随时发送数据
  • 使用 TCP 协议的通信双方,在进行数据传输之前,必须 使用 “ 三报文握手 ” 建立 TCP 连接 ,TCP 连接建立成功后才能进行数据传输。数据传输结束后,必须 使用 “ 四报文挥手 ” 来释放 TCP 连接

在这里插入图片描述

比较是否可以 单播、多播、广播

  • UDP 支持单播、多播以及广播。也就是支持一对一、一对多、一对全的通信。

  • TCP 仅支持单播 ,也就是一对一通信。

    使用 TCP 协议的通信双方,在进行数据传输之前,必须使用 “三报文握手” 来建立 TCP 连接。TCP 连接建立成功后,通信双方之间就好像是有一条可靠的通信信道进行通信。
    在这里插入图片描述

处理应用报文方式的比较

在这里插入图片描述

  • UDP 是面向应用报文的。

    UDP 对应用进程交下来的报文既不合并也不拆分,而是保留这些报文的边界。

  • TCP 是面向字节流的。

    1. 发送方的 TCP 把应用进程交付下来的数据块仅仅看作是一连串的、无结构的字节流。TCP 不知其含义,仅将它们编号并存储在自己的发送缓存中。TCP 根据发送策略,从发送缓存中提取一定数量的字节,构建 TCP 报文段并发送。
    2. 接收方的 TCP,一方面从所接收到的 TCP 报文段中取出数据载荷并存储在接收缓存中;一方面将接收缓存中的一些字节交付给应用进程。
    3. TCP 不保证接收方应用进程所收到的数据块与发送方应用进程所发出的数据块具有对应大小的关系。但接收方应用进程收到的字节流必须和发送方应用进程发出的字节流完全一样。

传输服务的比较

在这里插入图片描述

首部的比较

在这里插入图片描述
 

四、TCP 报文段


前文中提到,为了实现可靠传输,TCP 采用了 面向字节流 的方式。将应用进程交付下的应用报文看作字节流,存入到 TCP 的发送缓存 中。TCP 在发送数据时,是从发送缓存取出一部分或全部字节给其添加一个首部使其成为 TCP 报文段 后进行发送。如下图:

在这里插入图片描述

一个 TCP 报文段由 首部数据载荷 两部分构成。TCP 的全部功能都体现在它首部中各字段的作用。

TCP 报文段的首部格式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
 

五、TCP 的流量控制


一般来说,我们总是希望数据传输可以更快一些。但是如果发送方把数据发送得过快,接收方就可能来不及接收,这就会造成数据的丢失。

TCP 提供流量控制服务来消除发送方(发送速率太快)使接收方缓存区溢出的可能性。也就是让发送方的发送速率不要太快,要让接收方来得及接收。

采用 滑动窗口 机制可以很方便地在 TCP 连接上实现对发送方的流量控制。

  • 在通信过程中,接收方 根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,称为 接受窗口 rwnd,即调整 TCP 报文段首部中的 “窗口” 字段值,来限制发送方向网络注入报文的速率。
  • 同时,发送方根据其对当前网络拥塞程度的估计而确定的窗口值,称为 拥塞窗口 cwnd,其大小与网络的带宽和时延密切相关。

举例说明

实际上 TCP 发送方的 发送窗口为 rwnd 和 cwnd 中的最小值,此例中暂不考虑 cwnd。

例如,在通信中,有效数据只从 A 发往 B,而 B 仅向 A 发送确认报文。如下:
在这里插入图片描述

持续计时器 与 零窗口探测报文

在这里插入图片描述
为解决上面死锁的局面,TCP 为每一个连接设有一个 持续计时器

  1. 只要 TCP 连接的一方收到对方的零窗口通知,就启动持续计时器。若持续计时器超时,就发送一个零窗口探测报文,仅携带 1 字节数据。
  2. 而对方在确认这个探测报文段时,给出自己现在的接受窗口值。如果接收窗口仍为 0,那么收到这个报文段的一方就重新启动持续计时器;如果接收窗口不是 0,那么死锁局面就被打破了。

问题 1:接收窗口为 0 还怎么接收探测报文 ?

答:TCP 规定,即使接收窗口为 0,也必须接收零窗口探测报文段、确认报文段以及携带有紧急数据的报文段。

问题 2:如果零窗口探测报文也丢失了呢 ?

答:零窗口探测报文段也有重传计时器。

练习

在这里插入图片描述

六、TCP 的拥塞控制


在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏。这种情况就叫做 拥塞 。若出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降。见下图:
在这里插入图片描述

出现网络拥塞如何进行控制呢 ?

可以采用 慢开始、拥塞避免、快重传、快恢复 四种算法。
在这里插入图片描述

在这里插入图片描述

发送方维护一个叫做 拥塞窗口 cwnd 的状态变量,其值取决于网络的拥塞程度,并且动态变化。

  • 拥塞窗口的维护原则:只要网络没有出现拥塞,拥塞窗口就再增大一些;只要网络减少一些,拥塞窗口就减少一些
  • 判断出现网络拥塞的依据:没有按时收到应当到达的确认报文(即发生超时重传)

发送方将拥塞窗口作为 发送窗口 swnd,即 swnd = cwnd 。

发送方还需维护一个叫做 慢开始门限 ssthresh 的 状态变量:

  • 当 cwnd < ssthresh 时,使用慢开始算法
  • 当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法
  • 当 cwnd = ssthresh 时,即可使用慢开始算法,也可使用拥塞避免算法

慢开始和拥塞避免

1. 慢开始算法

在 TCP 刚刚连接好并开始发送 TCP 报文段时,先令拥塞窗口 cwnd = 1,即一个最大报文段长度 MSS。每收到一个对新报文段的确认后,将 cwnd 加 1,即增大一个 MSS。用这样的方法逐步增大发送方的 cwnd。cwnd 增大到一个规定的慢开始门限 ssthresh(阈值),然后改用 拥塞避免算法

说明:慢开始的 “慢” 并不是指 cwnd 增长速率慢,它是指数增长的。它的慢是说,开始时 cwnd = 1,只发送一个报文段。
 
2. 拥塞避免算法

其思路是让拥塞窗口 cwnd 缓慢增大。具体做法:每经过一个往返时延 RTT 就把发送方的拥塞窗口 cwnd 加 1,使其线性缓慢增大。
 
具体应用分析

无论慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(未按时收到确认),就要把慢开始门限 ssthresh 设置为出现拥塞时的发送方的 cwnd 值的一半(但不能小于 2)。

然后把拥塞窗口 cwnd 重新设置为 1,执行慢开始算法。
在这里插入图片描述
拥塞避免并不能完全避免拥塞,只是使网络比较不容易出现拥塞。

快重传和快恢复

有时,个别报文段会在网络中丢失,但实际上网络并没有出现拥塞。但是它导致了发送方超时重传,因此被误认为网络发生了拥塞。这使得传输效率有所降低。于是,快重传和快恢复算法对慢开始和拥塞避免算法进行了改进。

1. 快重传算法

所谓快重传,就是使发送方尽快进行重传,而不是等超时重传计时器超时再重传。这就要求发送方:

  1. 不要等待自己发送数据时才捎带确认,而是 要立即发送确认
  2. 即使收到了失序的报文段也要立即发出对已收到的报文段的 重复确认
  3. 一旦接收到 3 个连续的重复确认,就将相应的报文段 立即重传,而不是等待该报文段的超时重传计时器超时再重传。

在这里插入图片描述
对于个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞(进而降低拥塞窗口 cwnd 为 1)。使用快重传可以使整个网络的吞吐量提高约 20% 。
 
2. 快恢复算法

发送方一旦收到 3 个重复确认,就知道现在只是丢失了个别的报文段。于是不启动慢开始算法,而执行快恢复算法:

  1. 发送方 将慢开始门限 ssthresh 值和拥塞窗口 cwnd 值调整为当前窗口的一半(这是为了预防网络发生拥塞),而后开始执行拥塞避免算法。
  2. 也有的快恢复实现是把 cwnd 调整为 ssthresh + 3(网络没有发生拥塞,同时减少了 3 个报文段,可以适当把拥塞窗口扩大些)
    在这里插入图片描述

练习

在这里插入图片描述
这个题刚开始做时以为是快重传和快恢复,原因是没有注意到是发生了超时。发生超时应该使用慢开始和拥塞避免算法。

 

七、TCP 超时重传的选择


超时重传时间的选择是 TCP 最复杂的问题之一。

我们 不能直接使用某次测量得到的 RTT 样本来计算超时重传时间 RTO,如下图:
在这里插入图片描述

但是可以利用每次测量得到的 RTT 样本,计算 加权平均往返时间 RTTs(又称为平滑的往返时间)

测量方法如下所示,用这种方法得出的加权平均往返时间 RTTs 就比测量出的 RTT 值更加平滑
在这里插入图片描述

计算超时重传时间 RTO

显然,超时重传时间 RTO 应略大于加权平均往返时间 RTTs

RFC6298 建议使用下式计算超时重传时间 RTO:

在这里插入图片描述

往返时间 RTT 的测量

往返时间 RTT 的测量比较复杂。下面举两个例子来进行说明:
在这里插入图片描述

针对出现超时重传时无法测准往返时间 RTT 的问题,Karn 提出了一个算法:在计算加权平均往返时间 RTTs 时,只要报文段重传,就不采用其往返时间 RTT 样本

也就是说,出现重传时,不重新计算 RTTs ,进而超时重传时间 RTO 也不会重新计算。

此外,为解决时延突然增大并且长时间维持高时延时,报文段都会重传,导致超时重传时间无法更新,报文段反复重传的问题。需要 对 Karn 算法进行修正:报文段每重传一次,就把超时重传时间 RTO 增大一些。典型的做法时将新 RTO 的值取为旧 RTO 值的 2 倍

在这里插入图片描述

 

八、TCP 可靠传输的实现


TCP 基于 以字节为单位的滑动窗口 来实现可靠传输
在这里插入图片描述
如何描述发送窗口的状态?(编程实现)
在这里插入图片描述
TCP 可靠传输的实现还需注意以下几点:

在这里插入图片描述

习题

习题一
在这里插入图片描述
习题二
在这里插入图片描述
 

九、TCP 的运输连接管理


TCP 是面向连接的协议,它基于运输连接来传送 TCP 报文段。TCP 运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。TCP 的运输连接管理就是使 运输连接的建立和释放 都能正常地进行。

TCP 运输连接有以下三个阶段:

  1. 建立 TCP 连接
  2. 数据传送
  3. 释放 TCP 连接
    在这里插入图片描述

TCP 把连接作为最基本的抽象,每条 TCP 连接有两个端点,TCP 连接的端点不是主机,不是主机的 IP 地址,不是应用进程,也不是传输层的协议端口。TCP 连接的端口即为 套接字 或 插口,每条 TCP 连接唯一地被通信的两个端点(即两个套接字)确定。

TCP 连接的建立采用 客户/服务器方式 。主动发起连接建立的应用进程称为 客户(Client),而被动等待连接建立的应用进程称为 服务器(Sever)

TCP 的连接建立

TCP 的连接建立要解决以下三个问题

  1. 使 TCP 双方能够确知对方的存在
  2. 使 TCP 双方能够协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)
  3. 使 TCP 双方能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配

TCP 使用 “ 三报文握手 ” 建立连接
在这里插入图片描述

详细描述见 《计算机网络( 第7版 )》—— 谢希仁 P239

最初,两端的 TCP 进程都处于 CLOSED(关闭)状态。

一开始,TCP 服务进程首先创建 传输控制块 TCB(存储连接的重要信息,如 TCP 连接表、指向发送和接收缓存的指针、当前的发送和接收序号等),之后就准备接受连接请求。此时, TCP 服务器进程就进入了 LISTEN(收听) 状态,等待客户的连接请求。

TCP 客户进程也是首先创建 传输控制块 TCB 。然后,在打算建立连接时,分为以下三步进行操作:

  1. TCP 客户进程向 TCP 服务进程发送 TCP 连接请求报文段,并进入 SYN - SENT(同步已发送)状态。TCP 连接请求报文首部中的同步位置 SYN 被设置为 1,表明这时一个 TCP 连接请求报文段。序号字段 seq 被设置了一个初始值 x,作为 TCP 客户进程所选择的初始序号。

    注意: TCP 规定,SYN 被设置为 1 的报文段不能携带数据,但要消耗掉一个序号。

  2. TCP 服务进程收到连接请求报文端后,如果同意建立连接,则向 TCP 客户进程发送 TCP 连接请求确认报文段,并进入 SYN - RCVD(同步收到)状态。该报文段首部中的同步位 SYN 和确认位 ACK 都设置为 1,表明这时一个 TCP 连接请求确认报文段。序号字段 seq 被设置了一个初始值 y,作为 TCP 服务器进程所选择的初始序号。确认号字段 ack 的值被设置成了 x + 1,这是对 TCP 客户进程所选择的初始序号的确认。

    注意:确认报文段也不能携带数据,但也要消耗掉一个序号。

  3. 当 TCP 客户进程收到 TCP 连接请求确认报文段后,还要向 TCP 服务器发送一个普通的 TCP 确认报文段,并进入 ESTABLISHED(已建立连接)状态。该报文段首部中的确认位 ACK 被设置为 1,表明这是一个普通 TCP 确认报文段。序号字段 seq 被设置为 x + 1,这是因为 TCP 客户进程发送的第一个 TCP 报文段的序号为 x,因此第二个序号为 x + 1。确认号字段 ack 被设置为 y + 1,这是对 TCP 服务器进程所选择的初始序号的确认。TCP 服务器进程收到该确认报文段后,也进入 ESTABLISHED(已建立连接)状态。

    注意:TCP 规定,普通的 TCP 确认报文段可以携带数据。但如果不携带数据,则不消耗序号,这种情况下,所发送的下一个数据报文段序号仍是 x + 1。

思考一个问题:为什么 TCP 客户进程最后还要发送一个普通的 TCP 确认报文段呢 ? 能否简化为 “两报文握手” 来建立连接呢 ?

答案是否定的。这主要是为了防止已失效的连接请求报文段突然又传送到了 TCP 服务器进程,因而产生错误。如下图:
在这里插入图片描述

来道习题巩固一下
在这里插入图片描述

TCP 的连接释放

TCP 通过 “ 四报文挥手 ” 来释放连接

在这里插入图片描述

  1. 假设使用 TCP 客户进程的应用进程通知其主动关闭 TCP 连接,TCP 客户进程会发送 TCP 连接释放报文段,并进入 FIN - WAIT - 1(终止等待 1)状态。该报文段首部中的终止位 FIN 和确认位 ACK 的值都被设置为 1,表明这是一个 TCP 连接释放报文段,同时也对此前收到的报文段进行确认。序号 seq 字段设置为 u,它等于前面已传送过的、数据的最后一个字节的序号加 1。确认号 ack 字段的值设置为 v,它等于 TCP 客户进程之前已收到的、数据的最后一个字节的序号加 1。

    注意:TCP 规定,终止位 FIN 等于 1 的报文段即使不携带数据,也要消耗掉一个序号。

  2. TCP 服务器进程收到 TCP 连接释放报文段后,会发送一个普通的 TCP 确认报文段,并进入 CLOSE - WAIT(关闭等待)状态。该报文段首部中的确认位 ACK 的值被设置为 1,表明这是一个普通的 TCP 确认报文段。序号 seq 字段的值设置为 v,它等于 TCP 服务器进程之前已传送过的数据的最后一个字节的序号加 1。确认号 ack 字段的值设置为 u + 1,这是对 TCP 连接释放报文段的确认。

    TCP 服务器进程这时应通知高层应用进程:TCP 客户进程要断开与自己的 TCP 连接。此时,从 TCP 客户进程到 TCP 服务器进程这个方向上的连接就释放了,TCP 连接属于 半关闭状态 。但若服务器发送数据,客户进程仍要接收,即从服务器进程到客户进程这个方向上的连接未关闭。

  3. TCP 客户进程收到 TCP 确认报文段后就进入 FIN - WAIT - 2(终止等待 2) 状态,等待 TCP 服务进程发出的 TCP 连接释放报文段。若 TCP 服务器进程已没有数据发送,应用进程就通知其 TCP 服务器进程释放连接。TCP 服务器进程发送 TCP 释放报文段并进入 LAST - ACK(最后确认)状态。该报文段首部中的终止位 FIN 和确认位 ACK 都被设置为 1,表明这是一个 TCP 连接释放报文,同时也对之前收到的报文段进行确认。假设 seq 为 w,这是因为半关闭状态可能又发送了一些数据。确认号 ack 字段的值为 u + 1,这是对之前收到的 TCP 连接释放报文段的重复确认。

  4. TCP 客户进程收到 TCP 连接释放报文段后,必须针对该报文段发送普通的 TCP 确认报文段,之后进入 TIME - WAIT(时间等待)状态。该报文段首部中的 ACK 的值被设置为 1,表明这是一个普通的 TCP 确认报文段。序号 seq 字段的值设置为 u + 1,这是因为 TCP 客户进程之前发送的 TCP 连接释放报文段虽然不携带数据,但要消耗掉一个序号。确认号 ack 字段的值设置为 w + 1,这是对所收到的 TCP 连接释放报文段的确认。TCP 服务器进程收到该报文段后,就进入 CLOSED(关闭)状态。而 TCP 客户进程还需经过 2MSL 后才进入关闭状态。

MSL (Maximum Segment Lifetime):最大报文段寿命。RFC793 建议 2 分钟。对于目前的网络,2 分钟可能过长,因此 TCP 允许不同的实现可根据具体情况使用更小的 MSL 值。

又有一个问题:TCP 客户进程发送完最后一个确认报文段后,为什么不直接进入关闭状态,而是 2MSL 后才进入关闭状态 ?

在这里插入图片描述
主要原因有两点:

  1. 确保 TCP 服务器进程进入关闭状态。因为 TCP 客户进程发送的普通 TCP 确认报文段可能会丢失,TCP 服务器进程会对该报文段超时重传。但是由于没有等待 2MSL 时长 TCP 客户进程直接进入关闭状态,因为 TCP 客户进程无法对超时重传的报文进行确认,从而导致 TCP 服务器进程一直在超时重传无法进入关闭状态。
  2. 等待 2MSL 时间,可以使得本次连接中所产生的所有报文段都从网络中消失,避免影响下一次的连接。

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

imByte

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值