当前位置: 首页 > news >正文

计算机网络:运输层 - TCP首部格式 连接的创建与释放

计算机网络:运输层 - TCP首部格式 & 连接的创建与释放

    • TCP首部格式
      • 源端口 目的端口
      • 序号
      • 确认号
      • 数据偏移
      • 保留
      • 控制位
      • 窗口
      • 检验和
      • 紧急指针
    • TCP连接创建 - 三次握手
    • TCP传输过程
    • TCP连接释放 - 四次挥手


TCP首部格式

TCP的首部如下:

在这里插入图片描述

首部的前20 byte是固定的,后面的选项字段可变。

源端口 目的端口

源端口目的端口各占2 byte,即填入通信的两个进程使用的端口号。


序号

4 byte,范围是 [ 0 , 2 32 − 1 ] {\red{[0, 2^{32} - 1]}} [0,2321]TCP是面向字节流的,在TCP中传输的每一个字节都要按顺序进行编号。整个传输过程中,第一个字节的值是任意的,由发送方随机设定,后续所有字节都由第一个字节的编号以及偏移量得出。比如整个TCP连接中,第一个字节编号为x,那么第201个字节的编号就是x + 201

如果某个字节在编号时,超出了 2 32 − 1 2^{32} - 1 2321 ,此时从0开始重新计数。


确认号

4 byte,含义是:期望收到对方下一个报文段的第一个字节的序号

例如,主机B收到了来自A的编号为501的数据报,数据报长度为200。这说明主机B收到了编号为501 - 700字节的数据。那么主机B接下来就期望收到701开始的数据,此时确认号就设为701

若确认号为 n,说明 n - 1 及之前的所有数据都已经收到了


数据偏移

4 bit,其含义为:报文起始处数据起始处的距离,简单理解就是整个首部的长度

由于TCP带有填充字段,所以长度是不确定的,需要该字段来指明长度。另外的,由于只占该字段只占4 bit,能表示的范围是 [ 0 , 2 4 − 1 ] {\red{[0, 2^{4} - 1]}} [0,241],也就是[0, 15],而数据偏移字段以4 byte为单位。所以整个首部的长度最长为60 byte,进而说明选项字段的长度不超过40 byte


保留

6 bit,目前没有用,使用时设为全0


控制位

接着就是连续的留个控制位

紧急 URG:当URG = 1,表明紧急指针字段有效,告诉系统此报文有紧急数据,需要尽快传送,此时该报文就无需排队,直接插入到队列的首部立马发送出去。

确认 ACK:当ACK = 1时,确认号字段才有效。TCP规定:在连接建立后所有的传送报文段,ACK必须置为1

推送 PSH:发送该报文后,如果希望尽快收到对方的回应,就可以PSH = 1。接受方收到该报文后,会立刻把该报文提交给应用进程,而不是等到接收缓存满了才提交。

复位 RST:当RST = 1,表示TCP连接出现重大差错,必须释放连接。也可以用来拒绝一个连接或报文段。

同步 SYN:用于建立连接

  • SYN = 1并且ACK = 0,表明这是一个连接请求报文,(ACK = 0的情况,一般来说整个TCP连接只有此处ACK = 0)
  • SYN = 1并且ACK = 1,表明这是一个连接同意报文

终止 FIN:用于释放一个连接,当FIN = 1,表明这是一个释放连接的报文


窗口

2 byte,用于指明自己的接收窗口,对方收到该报文后,读取窗口字段,就知道自己接下来可以发送多少数据了。


检验和

2 byte,检验范围包括首部数据两部分,与UDP一样,在计算检验和时,要加上伪首部

如图:

在这里插入图片描述

只有计算检验和时才会存在伪首部,实际上其不存在,TCP 数据报中只有首部数据


紧急指针

2 byte,仅在URG = 1时才有效。当URG = 1,说明这是一个紧急的报文,此时要立刻发出去,整个数据报会插队到其他数据报的前面。那么计算机怎么知道这个紧急报文的长度是多少?

此时就需要紧急指针字段,其指明了本报文中紧急数据的字节数,当把所有紧急数据处理完后,就要恢复正常状态,把之前的数据发送出去。而什么时候紧急数据发送完,就是依靠紧急指针字段指明的紧急数据的字节数。


讲解完报文的格式后,我们来讲解TCP连接的创建与释放。后续会用到一些标识符,接下来我解释一下每个标识符对应数据报首部的哪一个字段:

  • seq:对应首部中的序号字段,指明希望收到的下一个数据的序号是什么
  • ack:对应首部中的确认号字段,表明xxx之前的所有数据都已经收到了
  • ACK:对应首部中的确认位字段,表明确认号有效
  • SYN:对应首部中的同步位字段,用于创建TCP连接
  • FIN:对应首部中的终止位字段,用于终止TCP连接

TCP连接创建 - 三次握手

假设现有一台客户主机A,一台服务器主机B,现在A申请向B发起TCP连接

处于创建连接的过程中,SYN就起作用了,如图:

在这里插入图片描述

首先令SYN = 1,表明当前正在创建连接,创建连接的报文分两种情况:

  • SYN = 1并且ACK = 0,表明这是一个连接请求报文,(ACK = 0的第一种情况)
  • SYN = 1并且ACK = 1,表明这是一个连接同意报文

当前A正在发起连接的请求,所以此时ACK = 0,注意:后续只要不标明的位,都是0

而发送数据是要对每个字节进行编号的,第一个字节的编号由主机随机生成,此时seq = x表明:第一个字节的编号为x

A发起请求后,此时B就要同意这个连接:

在这里插入图片描述

同意连接是SYN = 1ACK = 1,表明当前报文用于同意一个连接。此时主机B也要生成第一个字节的编码,也就是seq = y

B在回应时,还有一个字段ack = x + 1ack表示:我希望收到的下一个数据的编号。

比如说某一次报文发送时,第一个字节的编号为666,总数据长度为200 byte,那么接收方就收到了[666, 865]的所有数据,此时回应报文为ack = 866表明下一个数据的编号为866

那么目前来说刚刚TCP请求报文的编号为seq = x,现在我回应ack = x + 1,是不是可以理解为:整个TCP请求报文只携带一个字节的数据呢?

TPC规定:SYN = 1的报文不允许携带数据,但是消耗掉一个seq

其实SYN = 1的报文不携带数据部分,但是TCP强制规定了其要消耗掉一个seq,因此刚刚序号x视为被消耗了,下一个字节的序号为x + 1

A收到B的确认后,此时A也要再给B做一次确认:

在这里插入图片描述

这个确认,是对第二个报文的确认,此时SYN = 0,因为其既不是连接请求,也不是连接同意ACK = 1表明ack字段有效。seq = x + 1,因为第一个报文seq = x,并且SYN = 1要消耗掉一个需要,此时就用下一个序号x + 1

ack = y + 1是因为,刚刚B发送的报文seq = y,而SYN = 1要消耗掉一个序号,此时希望收到的下一个序号为y + 1

接下来考虑一个问题:为什么需要三次报文交换才能建立连接?明明A发送一个请求,B发送一个同意,就表明双方都准备建立连接了,为什么不直接开始传输数据,而是还要第三次确认?

这是因为在B发送第二个同意报文后,A可能还没准备好接收数据。比如说B发送的同意报文丢失了,此时A还在等待B的同意,而B以为A已经可以发送数据了。结果B发送了一段数据后,A根本不接收,因为A在等B的同意。此时就是A没有准备好。

因此A要发送第三个报文,来表明自己已经准备好了,对面可以开始发送数据了。

另外的,第三个报文是可以携带数据的,此时A发送第三个报文时,表明连接建立完毕了,于是A就顺带可以把一部分数据先通过该报文传输过去!

对于FIN = 0SYN = 0ACK = 1的报文,可以携带数据,携带多少数据就消耗多少序号,如果不携带数据,就不消耗序号

现在连接已经创建完毕,就可以正常数据传输了!


TCP传输过程

很多地方都只讲了连接创建与释放的过程,反而没有说明传输的过程。其实这个过程也很重要,本博客再简单讲解一下传输的过程。

如图所示:

在这里插入图片描述

现在TCP连接建立时,第三个报文携带了100个数据(data用于说明这个报文携带了多少数据)。

随后A又紧接着发送了300个数据:

在这里插入图片描述

此时seq = x + 101,这是因为刚刚的第三个报文携带了100 byte的数据,其中第一个字节的编号为x + 1,说明我已经把[x + 1, x + 100]的数据发出去了,接下来的300字节,第一个编号就是x + 101了。

ack = y + 1,这是因为上一次收到B的报文是SYN = 1ACK = 1的连接同意报文,序号为y,消耗掉一个序号后变为y + 1,即下一个希望收到的编号为y + 1

随后B发送了一个长度为200 byte的报文:

在这里插入图片描述

此时seq = y + 1,这是因为上一次B发送的报文是seq = y,而SYN = 1消耗掉一个序号,这次第一个字节使用的序号为y + 1ack = x + 401表明[x, x + 400]的所有数据都收到了,下一个希望收到的序号是x + 401

随后A再发送一个100 byte的报文:

在这里插入图片描述

这时seq = x + 401,因为之前发送了[x, x + 400]的数据,下一个字节编号为x + 401ack = y + 201表明[y, y + 200]的数据都受到了。

以此类推,直到连接释放。


TCP连接释放 - 四次挥手

TCP连接传输数据完毕,此时就可以释放连接了。

TCP连接释放可以由任意一方发起,假设现在A发起释放连接:

在这里插入图片描述

首先要把FIN = 1,表明A发起了一个释放连接的请求。而seq = u,表明当前的报文编号为u,也说明之前A传输的最后一个字节编号为u - 1ack = v,表明A收到的来自B的最后一个字节是u

A发起释放连接的请求,只说明A要传送的数据已经完毕了,可以释放连接了。但是B可能还有没有传送完的数据

在这里插入图片描述

首先B发送一个ACK报文,表明自己已经收到了刚刚FIN = 1的报文。

TCP规定:FIN = 1的报文,就算不携带数据也要消耗一个序号

A发送的连接释放报文中,FIN = 1并且不携带数据,那么也要消耗掉一个序号。因此B希望收到的下一个序号是u + 1

如果B收到该报文,那么ack = u + 1,否则ack = u,这样发送方就可以根据下一个报文得知B有没有收到连接释放的请求包围了

随后B可以继续发送自己之前没发完的数据,这期间B发送的报文FIN = 0,表明B还有数据要发,没这么快终止连接。

剩下B发送的所有报文中ack = u + 1,因为刚刚A发送了一个FIN = 1的报文。

seq = v,表明自己现在发送的数据中,第一个字节序号为v

B传输完自己的所有数据后,在发送释放连接的同意报文:

在这里插入图片描述

FIN = 1表明这是一个连接释放的报文,在两个FIN = 1的报文中间,B还发了一些报文,导致序号一直增加,假设现在增加到了w,那么seq = w

B发送完最后一个FIN = 1的连接释放报文后,A最后发送一个确认报文:

在这里插入图片描述

这是因为B无法保证自己发出去的报文A一定可以接收到,如果B发送的FIN = 1的报文丢失了,此时B以为自己以为结束TCP连接,而A还在一直等待B发出FIN = 1的报文。所以要对这个FIN = 1的报文最后做一次确认。

当这四个报文传输完毕,A不能直接结束,而要等待2 MSL

在这里插入图片描述

MSL(Maximum Segment Lifetime,最大报文段生存时间):指的是一个 TCP 报文在网络中存活的最长时间。

这是因为A传送的最后一个确认报文也有可能丢失,B如过发现A没有回应,超时计时器结束就重传FIN = 1的报文。而这个报文一定可以在2 * MSL期间到达,所以如果A2MSL期间没有收到B的报文,说明最后一个报文B收到了,可以释放连接了。


相关文章:

计算机网络:运输层 - TCP首部格式 连接的创建与释放

计算机网络:运输层 - TCP首部格式 & 连接的创建与释放 TCP首部格式源端口 目的端口序号确认号数据偏移保留控制位窗口检验和紧急指针 TCP连接创建 - 三次握手TCP传输过程TCP连接释放 - 四次挥手 TCP首部格式 TCP的首部如下: 首部的前20 byte是固定的…...

妈耶!被夸爆的零售数据分析方案在这里

在竞争激烈的零售市场中,数据分析已成为企业决胜的关键。今天,就为大家揭秘一份备受赞誉的零售数据分析方案——奥威BI零售数据分析方案,它围绕“人、货、场、供、财”五大主题,助力企业精准决策,实现业务增长。 一、人…...

AI探索:最佳落地应用场景

如果说今年的风口,那一定是 AI。不过AI像一把双刃剑,既有助益也有风险。我们将从IBM Watson的高飞与坠落,到Google Allo的黯然失色,探索AI应用中的教训。同时,瑞幸咖啡的成功故事展现了凭借策略得当的AI应用&#xff0…...

2024年最新机动车签字授权人考试题库。

31."简易瞬态工况法"所使用的五气分析仪的温度范图:分析系统及相关部件应在( )。 A.0-40℃ B.0-50℃ C.0-60℃ D.-10-40℃ 答案:A 32.稀释氧传感器环境空气量程检测时的读数值位于( )%vol范围之外时,应…...

软RAID

硬盘 连续空间 无法 扩容 lvm 非连续空间 可以动态扩容 raid 备份, 提高读写性能,不能扩容 raid 是磁盘的集合,按照排列组合的方法不 一,给 raid 去了不同的名字 raid0 raid1 raid5 raid10 什么是 RAID "RAID"…...

IDEA 学习之 启动“卡死”

目录 1. 断点问题2. IDEA 版本问题 1. 断点问题 部分断点涉及应用启动,会导致启动“卡死” 2. IDEA 版本问题 部分 IDEA 版本存在启动问题,本人之前遇到过(别人启动三分钟,我启动半个小时)。更换别的版本&#xff…...

豆瓣高分项目管理书籍推荐

📬豆瓣网站上有很多项目管理领域的书籍获得了较高的评分,以下是一些高分项目管理书籍的精选列表,发出来跟大家分享一下: 《项目管理知识体系指南(PMBOK指南)》 【内容简介】这本书是美国项目管理协会&…...

关于docker存储overlay2相关问题

报错如下: 报错原因:使用rm -rf 清理overlay2导致的,非正常清理。 正常清理命令如下: # 清理Docker的所有构建缓存 docker builder prune# 删除旧于24小时的所有构建缓存 docker builder prune --filter "until24h"#删…...

实现批量自动化电商数据采集|商品详情页面|店铺商品信息|订单详情数据

电商数据采集是指通过技术手段获取电商平台上的商品信息、店铺信息和订单信息等数据。这些数据可以用于市场分析、竞品分析、用户行为分析等。 商品详情页面是指电商平台上展示商品详细信息的页面,包括商品名称、价格、图片、描述、评价等信息。通过采集商品详情页…...

ES6(ECMAScript 6.0) 新特性

1 ES6 基本介绍 (1)ECMAScript 6.0(简称 ES6)是 JavaScript 语言的下一代标准, 2015 年 6 月发布。 (2)ES6 设计目标:达到 JavaScript 语言可以用来编写复杂的大型程序,成为企业级开发语言 &…...

性能工具之 JMeter 常用组件介绍(八)

文章目录 一、Jmeter命令行启动二、Jmeter脚本录制 本文主要介绍JMeter命令行启动和脚本录制功能 一、Jmeter命令行启动 Jmeter有两种运行: 一种是采用的界面模式(GUI)启动,会占用不少系统资源;另一种是命令行模式(n…...

分布式锁(Redission)

分布式锁: 使用场景: 通常对于一些使用率高的服务,我们会进行多次部署,可能会部署在不同的服务器上,但是他们获取和操作的数据仍然是同一份。为了保证服务的强一致性,我们需要对线程进行加锁,…...

【ARMv8/v9 GIC 系列 3 -- GIC 的 类型寄存器 GICD_TYPER】

文章目录 GIC 类型寄存器 GICD_TYPERESPI_Range, 位[31:27]RSS, 位[26]No1N, 位[25]A3V, 位[24]IDBits, 位[23:19]DVIS, 位[18]LPIs, 位[17]MBIS, 位[16]NUM_LPIs, 位[15:11]SecurityExtn, 位[10]NMI, 位[9]ESPI, 位[8]CPUNumber, 位[7:5]ITLinesNumber, 位[4:0]GIC 类型寄存器…...

MATLAB算法实战应用案例精讲-【数模应用】线性判别分析(附MATLAB、python和R语言代码实现)

目录 前言 算法原理 什么是判别分析 线性判别分析(LDA) 数学模型 二分类 多分类LDA ​编辑 算法思想: 费歇(FISHER)判别思想 贝叶斯(BAYES)判别思想 LDA算法流程 LDA与PCA对比 SPSSPRO 1、作用 2、输入输出描述 3、案例示例 4、案例数据 5、案例操作 …...

打造智能家居:用ESP32轻松实现无线控制与环境监测

ESP32是一款集成了Wi-Fi和蓝牙功能的微控制器,广泛应用于物联网项目。它由Espressif Systems公司开发,具有强大的处理能力和丰富的外设接口。下面我们将详细介绍ESP32的基础功能和引脚功能,并通过具体的实例项目展示其应用。 主要功能 双核处…...

大型Web应用的模块化与组织实践:Flask Blueprints深入解析

目录 一、引言 二、Flask Blueprints概述 三、Flask Blueprints的使用 创建Blueprint对象 定义路由和视图函数 注册Blueprint 使用Blueprints组织代码 四、案例分析 创建模块目录结构 创建Blueprint对象 注册Blueprint 五、代码示例与最佳实践 1. 代码示例 …...

AI 智算产业发展现状和预测报告

一、引言 2023年,随着ChatGPT的横空出世,人工智能领域迎来了新的浪潮。我们正站在一个技术革命的前沿,迈入一个全新的智算时代。在这个时代,更高效的计算、更智能的推理、更敏捷的内容生成,正在重新定义着生产力和生产组织形态。2023年《数字中国建设整体布局规划》的发布…...

【软件工具】Xshell安装教程

1、安装软件:Xshell-5.0.1337p.exe,双击安装即可,可以选择安装到D盘; 2、在D盘安装完成后,将文件nslicense.dll拷贝到对应的安装目录下; 3、打开快捷方式即可打开应用软件。...

git如何切换到tag分支

项目场景: 当我们需要回退到某个tag分支。 问题描述 通过git命令 git checkout tag_name 执行这个命令后,会提示你当前处于一个“detached HEAD”的状态。 原因分析: 这是因为tag只是一个快照,是不能更改代码的。 解决方案&am…...

【启明智显产品介绍】Model3C工业级HMI芯片详解专题(三)通信接口

Model3C 是一款基于 RISC-V 的高性能、国产自主、工业级高清显示与智能控制 MCU, 集成了内置以太网控制器,配备2路CAN、4路UART、5组GPIO、2路SPI等多种通信接口,能够轻松与各种显示设备连接,实现快速数据传输和稳定通信,可以与各…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

线程同步:确保多线程程序的安全与高效!

全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

uniapp中使用aixos 报错

问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...