【计算机网络】TCP三次握手,四次挥手以及SYN,ACK,seq,以及握手次数理解
TCP三次握手图解

描述
-
第一次握手:客户端请求建立连接,发送同步报文(SYN=1),同时随机一个seq=x作为初始序列号,进入SYN_SENT状态,等待服务器确认
-
第二次握手:服务端收到请求报文,如果同意建立连接,则发送同步确认报文 (SYN=1,ACK=1),确认号 ack=x+1,随机一个seq=y作为初始序列号,进入SYN_RECV状态
-
第三次握手:客户端收到服务端确认,发送确认报文(ACK=1),确认号ack=y+1,序列号seq=x+1,双方都进入ESTABLISHED状态,完成三次握手
TCP 三次握手时各标志位(SYN、ACK、ack、seq)的变化
| 步骤 | 发送方 | SYN | ACK | seq(序列号) | ack(确认号) | 状态变化 |
|---|---|---|---|---|---|---|
| ① 第一次握手 | 客户端 → 服务器 | 1 | 0 | x(随机初始值) | 无 | SYN_SENT(客户端等待服务器回应) |
| ② 第二次握手 | 服务器 → 客户端 | 1 | 1 | y(随机初始值) | x+1 | SYN_RECV(服务器等待客户端确认) |
| ③ 第三次握手 | 客户端 → 服务器 | 0 | 1 | x+1 | y+1 | ESTABLISHED(连接建立成功) |
各字段含义
- SYN(同步标志位):用于建立连接,表示请求同步序列号。
- ACK(确认标志位):表示确认前面接收到的数据。
- seq(序列号):表示数据包的起始字节编号,保证数据按顺序传输。
- ack(确认号):告诉对方你下一个数据要发的编号。
SYN 主要用于建立连接,ACK 用于确认数据,seq 和 ack 共同维护数据的顺序和完整性。
如何理解 TCP 的 seq(序列号)?
在 TCP 通信中,seq(序列号) 的作用是标识发送的数据字节流的顺序,确保数据包能按序到达,并且防止丢失和重复。
1. 在三次握手中的 seq 具体作用
在 TCP 三次握手 时,每一方都会选择一个随机的序列号 seq,作为自己即将发送数据流的起始编号,具体流程如下:
1️⃣ (第一次握手,客户端 → 服务器)
- 客户端 选择一个随机的初始序列号
x,并发送:SYN=1, seq=x - 含义:请求建立连接,并告诉服务器,我的初始序列号是
x,从x号字节开始传输数据。
2️⃣ (第二次握手,服务器 → 客户端)
- 服务器 收到请求,同意建立连接,并选择一个自己的初始序列号
y,回复:SYN=1, ACK=1, seq=y, ack=x+1 - 含义:
seq=y:表示服务器选择的初始序列号是y,数据从y号字节开始传输。ack=x+1:告诉客户端:「我已经收到你的 SYN 请求,并确认你的序列号x,下一次你发送数据时,请从x+1开始。」
3️⃣ (第三次握手,客户端 → 服务器)
- 客户端 收到服务器的确认后,回复:
ACK=1, seq=x+1, ack=y+1 - 含义:
seq=x+1:客户端告诉服务器:「我将从x+1号字节开始发送数据。」ack=y+1:告诉服务器:「我已经收到你的 SYN 请求,并确认你的序列号y,你下次发送数据时,从y+1开始。」
✅ 至此,三次握手完成,双方建立可靠连接,可以开始数据传输。
📌 结论
🔹 TCP 通过 seq(序列号)保证数据按顺序传输,不丢失,不重复,是 TCP 可靠传输的核心机制。
🔹 在三次握手中,seq 主要用于确定双方通信的起始位置,并避免历史连接数据混淆。
为什么需要三次握手,而不是两次?
如果只有两次握手,可能会导致历史连接请求的影响,从而引发服务器资源浪费或错误连接。
假设仅用两次握手:
- 客户端发送 SYN(请求建立连接)
- 服务器收到后直接发送 SYN-ACK 并建立连接
- 但是客户端可能已经超时,不再理会这个连接
这样,服务器会一直等待客户端的数据,导致资源浪费,甚至出现**半连接(Half-Open Connection)**问题。因此,第三次握手(ACK) 能确保客户端确实收到了服务器的回应,并正式建立连接,避免这种情况。
-
情景:在双方两次握手即可建立连接的情况下,假设客户端发送 A 报文段请求建立连接,由于网络原因造成 A 暂时无法到达服务器,服务器接收不到请求报文段就不会返回确认报文段。
-
客户端在长时间得不到应答的情况下重新发送请求报文段 B,这次 B 顺利到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,客户端在收到 确认报文后也进入 ESTABLISHED 状态,双方建立连接并传输数据,之后正常断开连接。
-
此时姗姗来迟的 A 报文段才到达服务器,服务器随即返回确认报文并进入 ESTABLISHED 状态,但是已经进入 CLOSED 状态的客户端无法再接受确认报文段,更无法进入 ESTABLISHED 状态,这将导致服务器长时间单方面等待,造成资源浪费。
为什么是三次,而不是四次?
三次握手让双方确认通信能力:
所谓确认通信能力就是双方都确认对方和自己的收发能力正常
-
在第一次握手 A确认自己可以发,B确认A可以发,自己可以收,发
-
第二次,A确认自己可以发可以收,B可以收可以发,但是此时B还不能确认A可以收,
-
所以有了第三次,此时,双方都确认对方和自己的收发能力正常
如果是四次握手:
-
额外的一次确认没有实际意义,因为三次握手已经确保了双方的通信能力。
-
额外的开销会降低效率,没有必要增加额外的握手步骤。
结论:
-
两次握手不够安全,可能导致服务器误认为连接已建立。
-
三次握手足够确保双方都能正常通信,并防止历史连接问题。
-
四次握手是多余的,没有额外的安全或可靠性提升,因此 TCP 采用三次握手。
TCP四次挥手图解

描述
- 第一次挥手:客户端向服务端发送连接释放报文(FIN=1,ACK=1),主动关闭连接,同时等待服务端的确认。
序列号 seq = u,即客户端上次发送的报文的最后一个字节的序号 + 1
确认号 ack = k, 即服务端上次发送的报文的最后一个字节的序号 + 1 - 第二次挥手:服务端收到连接释放报文后,立即发出确认报文(ACK=1),序列号 seq = k,确认号 ack = u + 1。
这时 TCP 连接处于半关闭状态,即客户端到服务端的连接已经释放了,但是服务端到客户端的连接还未释放。这 表示客户端已经没有数据发送了,但是服务端可能还要给客户端发送数据。 - 第三次挥手:服务端向客户端发送连接释放报文(FIN=1,ACK=1),主动关闭连接,同时等待 A 的确认。
序列号 seq = w,即服务端上次发送的报文的最后一个字节的序号 + 1。
确认号 ack = u + 1,与第二次挥手相同,因为这段时间客户端没有发送数据 - 第四次挥手:客户端收到服务端的连接释放报文后,立即发出确认报文(ACK=1),序列号 seq = u + 1,确认号为 ack = w + 1。
此时,客户端就进入了 TIME-WAIT 状态。注意此时客户端到 TCP 连接还没有释放,必须经过 2*MSL(最长报文段寿命)的时间后,才进入 CLOSED 状态。而服务端只要收到客户端发出的确认,就立即进入 CLOSED 状态。可以看到,服务端结束 TCP 连接的时间要比客户端早一些。
为什么连接的时候是三次握手,关闭的时候却是四次握手?
服务器在收到客户端的 FIN 报文段后,可能还有一些数据要传输,所以不能马上关闭连接,但是会做出应答,返回 ACK 报文段.
接下来可能会继续发送数据,在数据发送完后,服务器会向客户单发送 FIN 报文,表示数据已经发送完毕,请求关闭连接。服务器的ACK和FIN一般都会分开发送,从而导致多了一次,因此一共需要四次挥手。
为什么客户端的 TIME-WAIT 状态必须等待 2MSL ?
主要有两个原因:
-
确保 ACK 报文能够到达服务端,从而使服务端正常关闭连接。
第四次挥手时,客户端第四次挥手的 ACK 报文不一定会到达服务端。服务端会超时重传 FIN/ACK 报文,此时如 果客户端已经断开了连接,那么就无法响应服务端的二次请求,这样服务端迟迟收不到 FIN/ACK 报文的确认,就无法正常断开连接。
MSL 是报文段在网络上存活的最长时间。客户端等待 2MSL 时间,也就是两次报文发送时间:
假设客户端在传最后的ACK报文,但是没有发给服务端,然后服务端在这1MSL中没有接到客户端的ACK报文,于是再次发送FIN报文耗时1MSL打到客户端,刚好2MSL,客户端可以重新回应,而不至于在不等这2MSL的情况下直接关机如果服务端重发的 FIN 没有成功地在 2MSL 时间里传给客户端,服务端则会继续超时重试直到断开连接。
-
防止已失效的连接请求报文段出现在之后的连接中。
TCP 要求在 2MSL 内不使用相同的序列号。客户端在发送完最后一个 ACK 报文段后,再经过时间 2MSL,就可以保证本连接持续的时间内产生的所有报文段都从网络中消失。这样就可以使下一个连接中不会出现这种旧的连接请求报文段。或者即使收到这些过时的报文,也可以不处理它。
TIME-WAIT 状态过多会产生什么后果?怎样处理?
-
服务端: 短时间内关闭了大量的Client连接,就会造成服务器上出现大量的TIME_WAIT连接,严重消耗着服务器的资源,此时部分客户端就会显示连接不上。
-
客户端:客户端TIME_WAIT过多,就会导致端口资源被占用,因为端口就65536个,被占满就会导致无法创建新的连接。
-
解决办法:
-
服务端:设置 SO_REUSEADDR 套接字选项来避免 TIME_WAIT状态,此套接字选项告诉内核,即使此端口正忙(处于TIME_WAIT状态),也请继续并
重用它。 -
客户端:动态选择不同的源端口,避免因 TIME-WAIT 过多导致端口耗尽
https://github.com/0voice
相关文章:
【计算机网络】TCP三次握手,四次挥手以及SYN,ACK,seq,以及握手次数理解
TCP三次握手图解 描述 第一次握手:客户端请求建立连接,发送同步报文(SYN1),同时随机一个seqx作为初始序列号,进入SYN_SENT状态,等待服务器确认 第二次握手:服务端收到请求报文,如果同意建立连接…...
【Java】System 类
目录 静态字段标准输入输出流相关 常用静态方法数组操作时间操作系统操作属性操作安全管理 其他方法 System 类位于 java.lang 包下,是一个 final 类,意味着它不能被继承。并且其所有构造方法都是私有的,这使得我们无法创建 System 类的实例&…...
Zookeeper(80)Zookeeper的常见问题有哪些?
Zookeeper作为分布式系统的协调服务,常见的问题主要集中在配置、性能、连接管理、数据一致性和节点故障等方面。以下是一些常见问题及其详细解决方法和代码示例。 1. 配置问题 问题描述 配置不当可能导致 Zookeeper 集群无法正常启动或运行效率低下。 解决方法 …...
docker通用技术介绍
docker通用技术介绍 1.docker介绍 1.1 基本概念 docker是一个开源的容器化平台,用于快速构建、打包、部署和运行应用程序。它通过容器化技术将应用及其依赖环境(如代码、库、系统工具等)打包成一个标准化、轻量级的独立单元,实…...
Ubuntu 下 nginx-1.24.0 源码分析 - ngx_buf_t
ngx_buf_t 定义在 src/core/ngx_buf.h typedef struct ngx_buf_s ngx_buf_t;struct ngx_buf_s {u_char *pos;u_char *last;off_t file_pos;off_t file_last;u_char *start; /* start of buffer */u_char …...
Spring Data JPA 中的分页实现:从 BasePage 到 Pageable
文章目录 Spring Data JPA 中的分页实现:从 BasePage 到 Pageable背景:为什么需要分页?认识 BasePage 类深入 toPageable() 方法1. 处理页码和页面大小2. 处理排序方向3. 处理排序字段4. 生成 Pageable 对象 实战:如何使用 BasePa…...
自然语言处理NLP入门 -- 第八节OpenAI GPT 在 NLP 任务中的应用
在前面的学习中,我们已经了解了如何使用一些经典的方法和模型来处理自然语言任务,如文本分类、命名实体识别等。但当我们需要更强的语言生成能力时,往往会求助于更先进的预训练语言模型。OpenAI 旗下的 GPT 系列模型(如 GPT-3、GP…...
HTML:自闭合标签简单介绍
1. 什么是自结束标签? 定义:自结束标签(Self-closing Tag)是指 不需要单独结束标签 的 HTML 标签,它们通过自身的语法结构闭合。语法形式: 在 HTML5 中:直接写作 <tag>,例如 …...
智能家居遥控革命!昂瑞微HS6621EM:用「芯」定义AIoT时代的语音交互标杆
AIoT爆发期,遥控器为何成为智能家居的「隐形战场」? 随着Meta、苹果等巨头加速布局空间计算,智能家居生态正从「单一设备联网」向「全场景无感交互」跃迁。作为高频使用的入口设备,语音遥控器的性能直接决定用户体验天花板。昂瑞微…...
AI学习第七天
数组:基础概念、存储特性及力扣实战应用 在计算机科学与数学的广袤领域中,数组作为一种极为重要的数据结构,发挥着不可或缺的作用。它就像一个有序的 “数据仓库”,能高效地存储和管理大量数据。接下来,让我们深入了解…...
Grafana使用日志7--开启Sigv4
背景 在Grafana中,有些data source是需要开启sigv4认证的,例如OpenSearch,这个配置项默认是关闭的,这里我们介绍一下怎么开启 步骤 传统方式 如果我们想在Grafana中开启sigv4认证,我们需要在grafana.ini中修改一个…...
【Redis】Redis 入门
借鉴枫枫知道 一、连接 redis 1.1 命令行连接 // 完整的命令 redis-cli -h 127.0.0.1 -p 6379 -a password// 简写 redis-cli// 认证,进行redis之后 auth password1.2 go 代码连接 package mainimport ("fmt""github.com/go-redis/redis" …...
一文了解:部署 Deepseek 各版本的硬件要求
很多朋友在咨询关于 DeepSeek 模型部署所需硬件资源的需求,最近自己实践了一部分,部分信息是通过各渠道收集整理,so 仅供参考。 言归正转,大家都知道,DeepSeek 模型的性能在很大程度上取决于它运行的硬件。我们先看一下…...
15.14 QLoRA量化低秩适配微调:华盛顿大学的显存优化革命
QLoRA量化低秩适配微调:华盛顿大学的显存优化革命 一、技术架构解析 #mermaid-svg-Rkx3w3RQJ1e7odbb {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Rkx3w3RQJ1e7odbb .error-icon{fill:#552222;}#mermaid-svg-Rk…...
软件工程复试专业课-能力成熟度模型CMM
CMM CMM概念CMM的核心CMM来由CMM的目的成熟度等级初始级可重复级已定义级已管理级优化级 CMM概念 即能力成熟度模型,是对于软件组织在定义、实施、度量、控制和改善其软件过程的实践中各个发展阶段的描述。 CMM是改进软件过程的有效策略。它的基本思想是࿰…...
Dify使用和入门
第一步:了解 Dify 在开始之前,先简单了解一下 Dify 是什么: Dify 是一个开源的 LLM 应用开发平台,专注于帮助开发者快速构建生产级的生成式 AI 应用。它支持知识库集成、RAG(检索增强生成)技术、复杂工作…...
Mercury、LLaDA 扩散大语言模型
LLaDA 参考: https://github.com/ML-GSAI/LLaDA https://ml-gsai.github.io/LLaDA-demo/ 在线demo: https://huggingface.co/spaces/multimodalart/LLaDA Mercury 在线demo: https://chat.inceptionlabs.ai/ 速度很快生成...
Windows 图形显示驱动开发-WDDM 3.2-自动显示切换(十二)
API 更改 ADS 功能增加了以下公共 API 功能: 枚举系统中的多路复用器设备。查询有关多路复用器的信息,例如,它连接了哪些目标,以及当前切换到哪个目标。触发多路复用器切换。如何检测多路复用器是否已切换。 枚举系统中的多路复…...
Windows环境下SuperMapGIS 11i 使用达梦数据库
1. 环境介绍: 1.1. 操作系统: windows server 2019 1.2. GIS 软件: 1.2.1. GIS 桌面 supermap-idesktopx-11.3.0-windows-x64-bin 下载链接:SuperMap技术资源中心|为您提供全面的在线技术服务 安装教程:绿色版&…...
Claude 3.7 Sonnet深度解析:混合推理模型如何重塑AI编程能力
引言 2025年2月25日,人工智能领域领先企业Anthropic正式发布了新一代大语言模型Claude 3.7 Sonnet。作为全球首个混合推理AI模型,Claude 3.7 Sonnet在编程开发、逻辑推理以及任务处理效率等方面实现了突破性进展。本文将从核心特性、性能评测、竞品对比…...
IP属地是通过卫星定位的吗?如何保护用户隐私
在数字时代,网络空间成为了人们日常生活不可或缺的一部分。随着社交媒体、在线服务等平台的兴起,用户IP属地信息的重要性日益凸显。然而,关于IP属地是如何确定的,尤其是是否通过卫星定位这一问题,却常常引发公众的疑问…...
金融赋能绍兴纺织 民生银行助力外贸中小微企业“走出去”
在浙江绍兴,纺织业作为一张熠熠生辉的产业名片,承载着深厚的历史底蕴与蓬勃的发展活力。这里依傍长三角经济圈,交通网络纵横交错,将原材料产地与广阔市场紧密相连;产业集群高度成熟,上下游产业链完备&#…...
标记符号“<”和“>”符号被称为“尖括号”或“角括号”
你提到的“<”和“>”符号被称为“尖括号”或“角括号”。它们常用于编程语言中表示类型参数(如泛型)、HTML标签(如<div>)、数学中的不等式(如< 5)等。 好的,我来用通俗的方式解…...
一键部署DeepSeek
腾讯Cloud Studio提供DeepSeek一键部署功能,0行代码,秒级部署使用! 重点是每月免费提供10000分钟! 不用等待模型下载,创建即可使用。 内置 Ollama、DeepSeek-R1 1.5B、7B、8B、14B 及 32B 模型。 热门模板 AI模板 前…...
科普:ROC AUC与PR AUC
在评价二分类模型性能时,有许多评价指标,其中,有一对是用面积AUC(Area Under the Curve)做评价的:ROC AUC与PR AUC 本文我们对ROC AUC与PR AUC进行多维度对比分析: 一、定义与核心原理 维度RO…...
自动化测试无法启动(java.net.SocketException)
在运行测试代码,对浏览器进行自动化操作时,遇到了以下问题,添加依赖,编写了测试代码,但是程序无法运行 这个有两种原因(我使用的是谷歌浏览器): 网络问题: 因为需要从GitHub上下载对应包,所以有时候可能会出现网络问题,这个时候可以打开VPN之后,重新对程序进行启动 浏览器版本…...
大白话解释xxl-job是什么 有什么用 怎么用
XXL-JOB是什么? XXL-JOB就像快递公司的“总调度中心”,专门帮你的程序在不同服务器之间协调和执行定时任务。比如你有个电商系统,每天凌晨要统计订单数据、每小时要发促销短信,这些定时任务交给XXL-JOB来统一管理,它能…...
STM32G473VET6 在 Keil MDK 下手动移植 FreeRTOS 指南
下面将详细介绍如何在 Keil MDK 环境下将 FreeRTOS 手动移植到 STM32G473VET6 微控制器上。内容涵盖工程创建、获取源码、文件组织、移植层适配、测试任务编写以及编译调试等步骤。 1. 工程搭建(Keil 项目创建) 创建基础工程:首先准备一个基…...
WPF中对滚动条进行平滑滚动
有时候我们在动态添加内容时,需要将滚动条滚动到指定内容处。 一般我们会调用ScrollViewer的ScrollToVerticalOffset(垂直方向)函数和ScrollToHorizontalOffset(水平方向)函数来控制滚动条滚动到指定位置。 正常滚动效…...
API,URL,Token,XML,JSON是干嘛的
API,URL,Token,XML,JSON是干嘛的 API的作用 API(Application Programming Interface,应用程序编程接口)是一组定义和协议,用于构建和交互软件应用程序。API允许不同的软件系统之间…...
