TCP 基础知识(一)

本文涉及的产品
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 1个月
简介: Hey guys ,我是 cxuan ,欢迎你阅读我这一期的文章。

Hey guys ,我是 cxuan ,欢迎你阅读我这一期的文章。

这是一篇详细介绍 TCP 各种特点的文章,内容主要包括 TCP 三次握手和四次挥手细节问题、TCP 状态之间的转换、TCP 超时和重传、关于 TCP 包失序和重复问题、TCP 的数据流与窗口管理、TCP 的拥塞控制,思维导图如下。

微信图片_20220416185728.png

TCP 是一种面向连接的单播协议,在 TCP 中,并不存在多播、广播的这种行为,因为 TCP 报文段中能明确发送方和接受方的 IP 地址。

在发送数据前,相互通信的双方(即发送方和接受方)需要建立一条连接,在发送数据后,通信双方需要断开连接,这就是 TCP 连接的建立和终止。

TCP 连接的建立和终止

如果你看过我之前写的关于网络层的一篇文章,你应该知道 TCP 的基本元素有四个:即发送方的 IP 地址、发送方的端口号、接收方的 IP 地址、接收方的端口号。而每一方的 IP + 端口号都可以看作是一个套接字,套接字能够被唯一标示。套接字就相当于是门,出了这个门,就要进行数据传输了。

TCP 的连接建 立 -> 终止总共分为三个阶段

微信图片_20220416185733.png

下面我们所讨论的重点也是集中在这三个层面。

下图是一个非常典型的 TCP 连接的建立和关闭过程,其中不包括数据传输的部分。

TCP 建立连接 - 三次握手

微信图片_20220416185737.png

  1. 服务端进程准备好接收来自外部的 TCP 连接,一般情况下是调用 bind、listen、socket 三个函数完成。这种打开方式被认为是 被动打开(passive open)。然后服务端进程处于 LISTEN 状态,等待客户端连接请求。
  2. 客户端通过 connect 发起主动打开(active open),向服务器发出连接请求,请求中首部同步位 SYN = 1,同时选择一个初始序号 sequence ,简写 seq = x。SYN 报文段不允许携带数据,只消耗一个序号。此时,客户端进入 SYN-SEND 状态。
  3. 服务器收到客户端连接后,,需要确认客户端的报文段。在确认报文段中,把 SYN 和 ACK 位都置为 1 。确认号是 ack = x + 1,同时也为自己选择一个初始序号 seq = y。这个报文段也不能携带数据,但同样要消耗掉一个序号。此时,TCP 服务器进入 SYN-RECEIVED(同步收到) 状态。
  4. 客户端在收到服务器发出的响应后,还需要给出确认连接。确认连接中的 ACK 置为 1 ,序号为 seq = x + 1,确认号为 ack = y + 1。TCP 规定,这个报文段可以携带数据也可以不携带数据,如果不携带数据,那么下一个数据报文段的序号仍是 seq = x + 1。这时,客户端进入 ESTABLISHED (已连接) 状态
  5. 服务器收到客户的确认后,也进入 ESTABLISHED 状态。

这是一个典型的三次握手过程,通过上面 3 个报文段就能够完成一个 TCP 连接的建立。三次握手的的目的不仅仅在于让通信双方知晓正在建立一个连接,也在于利用数据包中的选项字段来交换一些特殊信息,交换初始序列号

一般首个发送 SYN 报文的一方被认为是主动打开一个连接,而这一方通常也被称为客户端。而 SYN 的接收方通常被称为服务端,它用于接收这个 SYN,并发送下面的 SYN,因此这种打开方式是被动打开。

TCP 建立一个连接需要三个报文段,释放一个连接却需要四个报文段。

TCP 断开连接 - 四次挥手

数据传输结束后,通信的双方可以释放连接。数据传输结束后的客户端主机和服务端主机都处于 ESTABLISHED 状态,然后进入释放连接的过程。

微信图片_20220416185742.png

TCP 断开连接需要历经的过程如下

  1. 客户端应用程序发出释放连接的报文段,并停止发送数据,主动关闭 TCP 连接。客户端主机发送释放连接的报文段,报文段中首部 FIN 位置为 1 ,不包含数据,序列号位 seq = u,此时客户端主机进入 FIN-WAIT-1(终止等待 1) 阶段。
  2. 服务器主机接受到客户端发出的报文段后,即发出确认应答报文,确认应答报文中 ACK = 1,生成自己的序号位 seq = v,ack = u + 1,然后服务器主机就进入 CLOSE-WAIT(关闭等待) 状态。
  3. 客户端主机收到服务端主机的确认应答后,即进入 FIN-WAIT-2(终止等待2) 的状态。等待客户端发出连接释放的报文段。
  4. 这时服务端主机会发出断开连接的报文段,报文段中 ACK = 1,序列号 seq = v,ack = u + 1,在发送完断开请求的报文后,服务端主机就进入了 LAST-ACK(最后确认)的阶段。
  5. 客户端收到服务端的断开连接请求后,客户端需要作出响应,客户端发出断开连接的报文段,在报文段中,ACK = 1, 序列号 seq = u + 1,因为客户端从连接开始断开后就没有再发送数据,ack = v + 1,然后进入到 TIME-WAIT(时间等待) 状态,请注意,这个时候 TCP 连接还没有释放。必须经过时间等待的设置,也就是 2MSL 后,客户端才会进入 CLOSED 状态,时间 MSL 叫做最长报文段寿命(Maximum Segment Lifetime)
  6. 服务端主要收到了客户端的断开连接确认后,就会进入 CLOSED 状态。因为服务端结束 TCP 连接时间要比客户端早,而整个连接断开过程需要发送四个报文段,因此释放连接的过程也被称为四次挥手。

TCP 连接的任意一方都可以发起关闭操作,只不过通常情况下发起关闭连接操作一般都是客户端。然而,一些服务器比如 Web 服务器在对请求作出相应后也会发起关闭连接的操作。TCP 协议规定通过发送一个 FIN 报文来发起关闭操作。

所以综上所述,建立一个 TCP 连接需要三个报文段,而关闭一个 TCP 连接需要四个报文段。TCP 协议还支持一种半开启(half-open) 状态,虽然这种情况并不多见。

TCP 半开启

TCP 连接处于半开启的这种状态是因为连接的一方关闭或者终止了这个 TCP 连接却没有通知另一方,也就是说两个人正在微信聊天,cxuan 你下线了你不告诉我,我还在跟你侃八卦呢。此时就认为这条连接处于半开启状态。这种情况发生在通信中的一方处于主机崩溃的情况下,你 xxx 的,我电脑死机了我咋告诉你?只要处于半连接状态的一方不传输数据的话,那么是无法检测出来对方主机已经下线的。

另外一种处于半开启状态的原因是通信的一方关闭了主机电源 而不是正常关机。这种情况下会导致服务器上有很多半开启的 TCP 连接。

TCP 半关闭

既然 TCP 支持半开启操作,那么我们可以设想 TCP 也支持半关闭操作。同样的,TCP 半关闭也并不常见。TCP 的半关闭操作是指仅仅关闭数据流的一个传输方向。两个半关闭操作合在一起就能够关闭整个连接。在一般情况下,通信双方会通过应用程序互相发送 FIN 报文段来结束连接,但是在 TCP 半关闭的情况下,应用程序会表明自己的想法:"我已经完成了数据的发送发送,并发送了一个 FIN 报文段给对方,但是我依然希望接收来自对方的数据直到它发送一个 FIN 报文段给我"。下面是一个 TCP 半关闭的示意图。

微信图片_20220416185749.png

解释一下这个过程:

首先客户端主机和服务器主机一直在进行数据传输,一段时间后,客户端发起了 FIN 报文,要求主动断开连接,服务器收到 FIN 后,回应 ACK ,由于此时发起半关闭的一方也就是客户端仍然希望服务器发送数据,所以服务器会继续发送数据,一段时间后服务器发送另外一条 FIN 报文,在客户端收到 FIN 报文回应 ACK 给服务器后,断开连接。

TCP 的半关闭操作中,连接的一个方向被关闭,而另一个方向仍在传输数据直到它被关闭为止。只不过很少有应用程序使用这一特性。

同时打开和同时关闭

还有一种比较非常规的操作,这就是两个应用程序同时主动打开连接。虽然这种情况看起来不太可能,但是在特定的安排下却是有可能发生的。我们主要讲述这个过程。

通信双方在接收到来自对方的 SYN 之前会首先发送一个 SYN,这个场景还要求通信双方都知道对方的 IP 地址 + 端口号

下面是同时打开的例子

微信图片_20220416185757.png

如上图所示,通信双方都在收到对方报文前主动发送了 SYN 报文,都在收到彼此的报文后回复了一个 ACK 报文。

一个同时打开过程需要交换四个报文段,比普通的三次握手增加了一个,由于同时打开没有客户端和服务器一说,所以这里我用了通信双方来称呼。

像同时打开一样,同时关闭也是通信双方同时提出主动关闭请求,发送 FIN 报文,下图显示了一个同时关闭的过程。

微信图片_20220416185800.png

同时关闭过程中需要交换和正常关闭相同数量的报文段,只不过同时关闭不像四次挥手那样顺序进行,而是交叉进行的。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
缓存 网络协议 算法
CCNA 必备:Linux 网络基础知识入门及 tcp 协议(三)|学习笔记
快速学习CCNA 必备:Linux 网络基础知识入门及 tcp 协议
CCNA 必备:Linux 网络基础知识入门及 tcp 协议(三)|学习笔记
|
缓存 网络协议 安全
CCNA 必备:Linux 网络基础知识入门及 tcp 协议
一、交换机的弊端及优化方法 二、网络分层 三、TCP/IP协议栈 四、TCP/IP分层 五、TCP协议特性 六、TCP包头
CCNA 必备:Linux 网络基础知识入门及 tcp 协议
|
存储 缓存 网络协议
TCP 基础知识(四)
Hey guys ,我是 cxuan ,欢迎你阅读我这一期的文章。
TCP 基础知识(四)
|
网络协议 算法 Linux
TCP 基础知识(三)
Hey guys ,我是 cxuan ,欢迎你阅读我这一期的文章。
TCP 基础知识(三)
|
网络协议 数据安全/隐私保护
TCP 基础知识(二)
Hey guys ,我是 cxuan ,欢迎你阅读我这一期的文章。
TCP 基础知识(二)
|
存储 网络协议 前端开发
TCP/IP 基础知识总结(二)
要说我们接触计算机网络最多的协议,那势必离不开 TCP/IP 协议了,TCP/IP 协议同时也是互联网中最为著名的协议,下面我们就来一起聊一下 TCP/IP 协议。
TCP/IP 基础知识总结(二)
|
网络协议 程序员 网络性能优化
TCP/IP 基础知识总结(一)
要说我们接触计算机网络最多的协议,那势必离不开 TCP/IP 协议了,TCP/IP 协议同时也是互联网中最为著名的协议,下面我们就来一起聊一下 TCP/IP 协议。
TCP/IP 基础知识总结(一)
|
监控 网络协议 数据安全/隐私保护
TCP/IP协议基础知识|学习笔记
快速学习TCP/IP协议基础知识
TCP/IP协议基础知识|学习笔记
|
网络协议
TCP/IP编程 - 1) 基础知识
1. What Is a Socket?(什么是套接字)   A socket is an abstraction through which an application may send and receive data, in muchthe same way as an open-file handle allows an application to read and write data to stablestorage.   简单来说,套接字就是网络数据传输用的软件设备。
833 0