TCP的运输连接管理
TCP的运输连接管理
文章目录
- TCP的运输连接管理
- TCP报文格式简介
- 首部各个字段的含义
- 控制位(flags)
- TCP的连接建立
- 抓包验证
- 一些细节及解答
- TCP连接释放
- 抓包验证
- 一些细节及解答
- 参考
TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP运输连接的建立和释放时每一次面向连接的通信中必不可少的过程。因此,运输连接就有三个阶段,即: 连接建立、 数据传输、 连接释放。运输连接的管理就是使运输连接的建立和释放都能正常运行。
TCP的连接是一条 虚连接(也就是 逻辑连接 )
在TCP连接建立的过程中要解决以下三个问题:
- 要使每一方能够确知对方的存在。
- 要允许双方协议一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等)
- 能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。
TCP连接蚕蛹客户服务器方式。主动放弃连接建立的应用进程叫做客户,而被动等待连接建立的应用进程叫做服务器。
TCP最主要的特点
- TCP是面向连接的运输层协议。 这就是说在传送数据前必须先建立TCP连接。在传送完数据后必须释已经建立的TCP连接。
- 每一条TCP连接只能有两个端点,每一条TCP连接只能是点对点(一对一)
- TCP 提供可靠交付的服务。通过TCP连接传送的数据,无差错、不丢失、不重复,并且按序到达。
- TCP提供全双工通信。 TCP允许通信双档的应用进程在任何时候都能发送数据。TCP连接的两段都设有发送缓存和接受缓存,用来临时存放双向通信的数据。
- 面向字节流 TCP中的“流”指的是 流入到进程或从进程流出的字节序列。
面向字节流的含义是:虽然程序和TCP的交互是一次一个数据(大小不等),但TCP把应用程序交下来的数据仅仅看成是一串无结构的字节流。
TCP报文格式简介
TCP虽然是面向字节流的,但TCP传送的数据单元却是报文段。一个TCP报文段的分为首部和数据两部分,而TCP的全部功能都体现在它首部中各个字段的作用。下面我们就来看一下TCP报文段首部格式。

首部各个字段的含义
首部固定部分个字段的意思如下:
-
源端口和目的端口 各占2个字节,分别写入源端口号和目的端号。
-
序号(seq) 占4字节。序号范围是[0,232−1][0, 2^{32} - 1][0,232−1],共2322^{32}232个序号。序号增加到[0,232−1][0, 2^{32} - 1][0,232−1]后,下一个序号就又回到0。
-
确认号(ack) 占4字节,是期望收到对方下一个报文段的第一个数据字节的序号。
若确认号 = N, 则表明:到序号 N - 1为止的所有数据都已正确收到。
-
数据偏移 占4位,它指出TCP报文段的数据起始处距离TCP报文段的起始处有多远。换个说法是这个字段指出了TCP报文段的首部长度。
首部最小长度为20字节,因此数据偏移字段的最小值为(0101)2(0101)_2(0101)2.
首部最长长度为60字节,因此数据偏移字段的最小值为(1111)2(1111)_2(1111)2.
-
保留 占6位,保留为今后使用,但目前应置为0。
-
控制位(flags) 有6个控制位,用于说明本报文段的性质。 具体含义见下。
-
窗口 占2字节。窗口值是[0,216−1][0, 2^{16} - 1][0,216−1]之间的整数。窗口指的是发送本报文段的一方的接收窗口。窗口值告诉对方:从本报文段首部中的确认号算起,接收方目前允许发送的数据量(以字节为单位)。有这个限制的原因是接收方的数据缓存空间是优先的。窗口值作为接收方让发送方设置其发送窗口的依据。
窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化着。
-
检验和 占2字节。检验和字段检验的范围包括首部和数据这两部分。和UDP用户数据报一样,在计算检验和时,要在TCP报文段的前面加上12字节的伪首部。
-
紧急指针 占2字节。紧急指正仅在URG = 1时才有意义,它指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据)。因此,紧急指针指出了紧急数据的末尾在报文段中的位置。当所有紧急数据都处理完时。值得注意的是,即使窗口为零时也可发送紧急数据。
-
选项 长度可变,最长可达40字节。当没有使用“选项”时,TCP的首部长度是20字节。
随着互联网的发展出现了多个选项:
-
最大报文段长度 MSS. MSS是每一个TCP报文段中的**数据字段的最大长度**(不包含首部)。(最初只有这个)
-
窗口扩大 窗口扩大选项占3字节,其中一个字节表示移位值S.新窗口值等于TCP首部中的窗口位数从16增大到(16 + S)。移位值允许使用的最大值是14 ,相当于窗口最大值增大到216+14−1=230−12^{16 + 14} - 1 = 2^{30} - 1216+14−1=230−1。
为了使像卫星信道的网络提高吞吐量,需要更大的窗口。
-
时间戳 占10字节,其中最主要的字段是时间戳值(4字节)和时间戳回送回答字段(4字节)
发送方在发送报文段时把当前时钟的时间值放入时间戳字段,接收方在确认该报文段时把时间戳字段值复制到时间戳回送回答字段。因此,发送方在收到确认报文后,可以准确计算出RTT。
时间戳的两个功能:
① 用来计算往返时间RTT
② 用于处理TCP序号超过2322^{32}232的情况,这又称为 防止序号绕回 PAWS (Protect Against Wrapped Sequence numbers)
-
控制位(flags)
-
紧急 URG(URGent) 当 URG = 1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送,而不需要按原来的排队顺序来传送。例如,用户发出的中断命令,中断在远地的程序运行。
当URG置1时,发送方TCP就把紧急数据插入到报文段数据的最前面,而在紧急数据后面的数据任然是普通数据。这需要与首部中的紧急指针字段配合使用。
-
确认 ACK 仅当ACK = 1时确认号字段才有效,当ACK = 0 时,确认号无效。TCP规定,在建立连接后所有传输的报文段都必须把ACK置为1.
-
推送 PSH 当将PSH置为1,并发送出该TCP时。接收方就尽快地交付接收应用进程,而不再等到整个缓存都填满了后再向上交付。
-
复位 RST 当RST = 1时,表明TCP连接中出现严重错误,必须释放连接。RST还用来拒绝一个非法报文段或拒绝打开一个连接。RST也可以称为重建位或重置位。
-
同步 SYN (SYNchronization) 当SYN置为1时,表明这是一个连接请求报文段。
-
终止 FIN 用来释放一个连接。当FIN = 1时,表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。
TCP的连接建立
TCP建立连接的过程叫做握手,握手时需要在客户机和服务器之间交换三个报文段(也可以是四个)TCP报文段。下图为三报文握手建立TCP连接的过程。

如果在上一小节对TCP首部报文各字段都有了认识。下面对上面三条线的意思做如下语义化:
- A:你好,可以建立连接嘛?我的报文段序号为x。
- B:好的,接受你向我建立连接,期待你序号为x+1的报文段。我也可以向你建立连接嘛?我的报文序号为y。
- A:接受你发起的连接,期待你发送的序号为y+1的报文段,我发送数据的序号是x+1.
抓包验证
下面是通过抓包工具抓到的一些数,可以用来分析TCP的三次握手:

在图中红框选中显示的是完整的TCP连接的“三次握手”过程。
在6068->80过程中,6068是客户端端口,80是服务器的端口。在6068和80端口之间来回就是“三次握手”的过程。
可以看到“第一次握手”客户端发送的TCP报文中以[SYN]作为标志位,并且客户端序号seq = 0.
在第二次中服务端返回的TCP报文中以[SYN, ACK]作为标志位。同时发送服务端的序号seq = 0,确认号ack = 1(是”第一次握手“中客户端序号seq值 + 1)
“第三次握手”中客户端再向服务器发送的TCP报文中以ACK作为标志位。同时携带客户端序号seq = 1(第二次握手中服务器确认号ack的值);确认号ack = 1(第二次握手中服务端序号seq + 1)
通过上面三步客户端和服务端就建立了连接,符合前面的TCP连接的示意图。
一些细节及解答
为什么A最后还要发送一次确认呢?(为什么需要最后一次握手)
这主要是为了防止已失效的连接请求报文段突然又传到了B,因而产生了错误。
所谓的已失效请求报文段可以在以下场景中产生:
A先发送的连接请求报文,因种种原因延迟了。于是A又发送了请求连接报文,并且成功经历了连接、数据传送、断开连接。在断开连接之后A第一次发送的请求报文才刚到,于是B开始向A发出确认报文段,但是A并没有发出新的建立连接的请求,因此不会理睬B的确认。如果缺少最后一次握手,会导致B发出建立连接报文之后就认为连接建立,而A实际上并没有同意连接的建立。
TCP连接释放

四次挥手的理解:
(1) 首先客户端想要释放连接,向服务器端发送一段TCP报文,其中:
- 标记位为FIN,表示"请求释放连接"
- 序号为seq = u
- 随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。
注意:这里不发送的是正常连接时传输的数据(非确认报文),而不是一切数据,所以客户端仍然能发送ACK确认报文。
(2) 服务器接收到从客户端发出的TCP报文后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文,其中:
- 标记位ACK,表示“接收到客户端发送的释放连接的请求”
- 序号位seq = v
- 确认号为ack = u + 1,表示是在收到客户端报文的基础上,将其序号值加q作为本段报文确认号ack的值;
- 随后服务器端开始准备释放服务器端到客户端方向上的连接。客户端收到从服务器端发出的TCP报文后,确认了服务器收到了客户端发出的释放连接请求,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段
(3) 服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器到客户端方向上的连接准备,再次向客户端发出一段TCP报文,其中:
- 标记位为FIN,ACK,表示“已经准备好释放连接了”。注意这里的ACK并不是确认收到服务端的确认报文。
- 序号为seq = w
- 确认号为ack = u + 1,表示是在收到客户端报文的基础上,将其序号seq值加1作为本报文确认号ack的值。
随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。
(4) 客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务端发送一段报文,其中:
- 标记位ACK,表示接收到服务器准备号释放连接的信号
- 序号为seq = u + 1,表示在收到了服务器端报文的基础上,将其确认号ack值作为本报文序号的值。
- 确认号为ack = w + 1,表示是在收到了服务器端报文的基础上,将其序号seq值作为本段报文确认号的值
随后客户端开始在TIME-WAIT阶段等待2MSL.
抓包验证

上图为借助抓包工具,抓取到的TCP的四次挥手的过程。可以照前面的示意图和文字来看。发现与前面的描述一致。
一些细节及解答
为什么客户端在TIME-WAIT阶段要等2MSL?
这有两个理由:
① 为了保证A发送的最后一个ACK报文能够到达B.因为A发送的最后这个ACK报文可能丢失。如果A直接进入到CLOSE阶段跳过TIME-WAIT阶段的话,B在无法收到确认断开的报文段重新发送请求断开的报文段时,A将无法收到因为此时连接已经断开。
② 防止上一节提到的“已失效的连接请求报文段”出现在本连接中。在A发送完最后一个ACK报文段后,再经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中小时。这样就可以使下一个新的连接中不会出席那这种旧的连接请求报文段。
参考
-
《计算机网络 第7版》
-
详解 TCP 连接的“ 三次握手 ”与“ 四次挥手 ” (baidu.com)
-
TCP报文段的首部格式
相关文章:
TCP的运输连接管理
TCP的运输连接管理 文章目录TCP的运输连接管理TCP报文格式简介首部各个字段的含义控制位(flags)TCP的连接建立抓包验证一些细节及解答TCP连接释放抓包验证一些细节及解答参考TCP是面向连接的协议。运输连接是用来传送TCP报文的。TCP运输连接的建立和释放时每一次面向连接的通信…...
地级市用电、用水、用气数据指标
用电用水量和煤气及液化石油气供应及利用情况可以反映出城市基础设施的建设情况!之前我们基于历年的《中国城市统计年鉴》整理了1999—2020年的人口数量数据指标、人口变动数据指标、用地相关数据指标、污染物排放和环境治理相关数据指标、地区生产总值及一二三产构…...
安装deepinlinuxV20.8配置docker和vscode开发c语言
# 重装的原因 某个开发任务时,发现需要glibc2.25,本机版本比较低,就下载源码configure make makeinstall,结果失败了, 看来与系统用的glibc有冲突,造成部分库版本不一致,打开终端出现段错误&#x…...
java08-面向对象3
一:static 关键字:静态的 1.可以用来修饰的结构:主要用来修饰类的内部结构 属性、方法、代码块、内部类 2. static 修饰属性:静态变量(或类变量) 2.1 属性,是否使用static修饰,又分为静态属…...
【Spark分布式内存计算框架——Spark Core】8. 共享变量
第七章 共享变量 在默认情况下,当Spark在集群的多个不同节点的多个任务上并行运行一个函数时,它会把函数中涉及到的每个变量,在每个任务上都生成一个副本。但是,有时候需要在多个任务之间共享变量,或者在任务(Task)和…...
C++多态常见面试题
1.什么是多态 简单点说,就是多种形态,具体就是完成某个行为,当不同的对象去完成时产生的不同形态。多态分为静态多态和动态多态,静态多态一般指的是函数重载,在编译阶段通过函数名修饰规则,不同类型调用不同…...
字母板上的路径 题解,力扣官方出来挨打(小声)
字母板上的路径 我们从一块字母板上的位置 (0, 0) 出发,该坐标对应的字符为 board[0][0]。 在本题里,字母板为board [“abcde”, “fghij”, “klmno”, “pqrst”, “uvwxy”, “z”],如下所示。 我们可以按下面的指令规则行动:…...
代码随想录算法训练营第二十六天 | 39. 组合总和,40.组合总和II,131.分割回文串
一、参考资料组合总和题目链接/文章讲解:https://programmercarl.com/0039.%E7%BB%84%E5%90%88%E6%80%BB%E5%92%8C.html 视频讲解:https://www.bilibili.com/video/BV1KT4y1M7HJ 组合总和II题目链接/文章讲解:https://programmercarl.com/004…...
vueday01-脚手架安装详细
一、vue脚手架安装命令npm i -g vue/cli 或 yarn global add vue/cli安装上面的工具,安装后运行 vue --version ,如果看到版本号,说明安装成功或 vue -V工具安装好之后,就可以安装带有webpack配置的vue项目了。创建项目之前&#…...
初识cesium3d(一)
使用ViteVue3.2Cesium。Vite需要Node.js版本14.18及以上版本。Vite命令创建的工程会自动生成vite.config.js文件,来配置一些相关的参数。 1、使用Vite创建vue3项目 # npm npm init vitelatest cesium-app -- --template vue # yarn yarn create vite cesium-app…...
点云转3D网格【Python】
推荐:使用 NSDT场景设计器 快速搭建 3D场景。 在本文中,我将介绍我的 3D 表面重建过程,以便使用 Python 从点云快速创建网格。 你将能够导出、可视化结果并将结果集成到您最喜欢的 3D 软件中,而无需任何编码经验。 此外࿰…...
【OpenCV图像处理系列一】OpenCV开发环境的安装与搭建(Ubuntu + Window都适用)
🔗 运行环境:OpenCV,Ubuntu,Windows 🚩 撰写作者:左手の明天 🥇 精选专栏:《python》 🔥 推荐专栏:《算法研究》 #### 防伪水印——左手の明天 #### &#x…...
【代码随想录】-动态规划专题
文章目录理论基础斐波拉契数列爬楼梯使用最小花费爬楼梯不同路径不同路径 II整数拆分不同的二叉搜索树背包问题——理论基础01背包二维dp数组01背包一维数组(滚动数组)装满背包分割等和子集最后一块石头的重量 II目标和一和零完全背包零钱兑换 II组合总和…...
c++数据类型 输入输出
C++语法 //常用包: iostream:cin cout endl cstdio:scanf printf algorithm:max min reverse swap cstring:memset memcpymemset(a,-1,sizeof a) 填充数组memcpy(b,a,sizeof a) 将a数组复制到b数组,长度是a数组字节长度 cmath:sin sqrt pow abs fabs编程是一种控制计…...
【设计模式-11】责任链模式
认识设计模式(十一)---责任链模式【一】责任链模式【二】介绍(1)意图(2)主要解决(3)何时使用(4)如何解决(5)关键代码(6&am…...
SpringBoot+Vue实现智能物流管理系统
文末获取源码 开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7/8.0 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏…...
【MT7628】MT7628如何修改串口波特率、调试串口物理口、使用UART3口
环境说明 sdk版本:Mediatek_ApSoC_SDK_4320_20150414.tar.bz2 芯片方案:MT7628A Uboot修改串口波特率方法 修改rt2880.h文件 修改include/configs/rt2880.h文件CONFIG_BAUDRATE宏的值 - #define CONFIG_BAUDRATE 57600 +#define CONFIG_BAUDRATE 115200 Kernel中修改串口波特…...
css盒模型介绍
在使用CSS进行网页布局时,我们一定离不开的一个东西————盒子模型。盒子模型,顾名思义,盒子就是用来装东西的,它装的东西就是HTML元素的内容。或者说,每一个可见的 HTML 元素都是一个盒子,下面所说的盒子…...
onetab 谷歌插件历史数据清除
文章目录方法1:测试也可以步骤1:批量执行点击步骤2:python 脚本模拟点击确定操作方法2:成功【推荐】步骤1:修改confirm,类似于hook操作步骤2:批量点击删除操作:onetab 谷歌插件历史数…...
GRBL源码简单分析
结构体说明 GRBL里面的速度规划是带运动段前瞻的,所以有规划运动段数据和微小运动段的区分 这里的“规划运动段”对应的数据结构是plan_block_t,前瞻和加减速会使用到,也就是通过解析G代码后出来的直接直线数据或是圆弧插补出来的拟合直线数据…...
网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
