TCP 建链(三次握手)和断链(四次握手)
TCP 建链(三次握手)和断链(四次挥手)
- 背景
- 简介
- 建链(三次握手)
- 断链(四次挥手)
- 序号及标志位
- 延伸问题
- 为什么建立连接需要握手三次,两次行不行?
- 三次握手可以携带数据吗?
- 为什么释放连接是四次,比建立连接多一次?
- 为什么 `TIME_WAIT` 状态需要经过 `2MSL` 才能返回到 `CLOSED` 状态?
背景
随着年龄的增长,很多曾经烂熟于心的技术原理已被岁月摩擦得愈发模糊起来,技术出身的人总是很难放下一些执念,遂将这些知识整理成文,以纪念曾经努力学习奋斗的日子。本文内容并非完全原创,大多是参考其他文章资料整理所得,感谢每位技术人的开源精神。
简介
本文介绍 TCP 的建链和断链过程,即通常所说的三次握手和四次挥手的过程。
建链(三次握手)
TCP 建链需要客户端与服务器之间交互 3 个数据包,主要作用就是为了确认双方的接收和发送能力是否正常,初始序列号、交换窗口大小以及 MSS 等信息。

-
第一次握手
客户端发送请求连接数据包到服务器,标志位SYN置为1,随机生成一个初始序号seq,即SYN=1 seq=x,客户端从CLOSED状态进入SYN_SENT状态,等待服务器回复。 -
第二次握手
服务器收到请求数据包后根据标志位SYN=1知道客户端在请求建立连接,服务器将标志位SYN和ACK都置为1,确认序号ack=x+1,随机生成一个初始序号seq=y,并将该数据包SYN=1, ACK=1, seq=y, ack=x+1回复给客户端确认连接请求,服务器从LISTEN状态进入SYN_RCVD状态。 -
第三次握手
客户端收到确认后检查确认序号ack是否为x+1,ACK是否为1,如果正确则将标志位ACK置为1,确认序号ack=y+1,并将该数据包ACK=1, seq=x+1, ack=y+1发送给服务器,发送完成后客户端进入ESTABLISHED状态,服务器接收到后检查确认序号ack是否为y+1,如果正确则连接建立成功,服务器进入ESTABLISHED状态。随后客户端与服务器间可以开始传输数据。
断链(四次挥手)

-
第一次挥手
客户端发起FIN包FIN=1, ACK=1, seq=u, ack=v,客户端从ESTABLISHED状态进入FIN_WAIT_1状态。TCP 协议规定,即使FIN包不携带数据,也要消耗一个序号。此FIN包中ACK=1和ack=v基于断链前正常通信的数据包。 -
第二次挥手
服务器收到FIN包,发出ACK确认包,并带上自己的序号seq=v(ACK=1 seq=v ack=u+1),服务器进入从ESTABLISHED状态进入CLOSE_WAIT状态。此时客户端已经没有数据需要发送给服务器了,但服务器如果仍有数据发送给客户端的话,客户端依然需要接收。客户端接收到服务器发送的ACK后进入FIN_WAIT_2状态。 -
第三次挥手
服务器数据发送完成后向客户端发送FIN包FIN=1, ACK=1, seq=w, ack=u+1,半连接状态下服务器可能又发送了一些数据,假设发送seq为w,服务器进入LAST_ACK状态。 -
第四次挥手
客户端接收到服务器的FIN包后发出确认包ACK=1, seq=u+1, ack=w+1,客户端进入TIME_WAIT状态,此时 TCP 连接还没有释放,必须经过2*MSL后才进入CLOSED状态,而服务器接收到客户端的ACK后就进入了CLOSED状态,服务器结束 TCP 连接的时间要比客户端早一些。
序号及标志位
TCP 建链(三次握手)和断链(四次挥手)中涉及到几个关键概念字段:
- 标志位:共有 6 个,分别是:
ACK:确认序号有效。FIN:释放一个连接。PSH:接收方应该尽快将这个报文交给应用层。RST:重置连接。SYN:发起一个新连接。URG:紧急指针(urgent pointer)有效。
seq:Seq 序号,占32位,用来标识从 TCP 源端向目的端发送的字节流,发起方发送数据时对此进行标记。ack:Ack 序号,占32位,只有ACK标志位等于1时此序号字段才有效,确认方ack等于发起方seq + 1。注意:ACK和ack是两个不同的概念,不要混淆了。
延伸问题
为什么建立连接需要握手三次,两次行不行?
- 原因一:TCP连接建立前需要确认客户端和服务器双方的收发包能力。
- 第一次握手可以让服务器知道客户端的发送能力是正常的。
- 第二次握手可以让客户端知道服务器的接收和发送能力都是正常的。
- 第三次握手可以让服务器指导客户端的接收能力是正常的。
- 原因二:确保序列号可靠同步。
第二次握手服务器向客户端发送了自己的初始序列号,如果第二次握手报文丢失则客户端就无法知道服务器的初始序列号,所以需要第三次握手让服务器知道客户端已确认服务器的初始序列号。 - 原因三:阻止重复历史连接的初始化。
客户端由于某种原因发送了两个不同序号的SYN包,因为复杂的网络环境中旧的数据包有可能先到达服务器,如果是两次握手则服务器收到旧的SYN包就会立刻建立连接,从而造成网络异常。如果是三次握手,服务器需要回复SYN+ACK包,客户端会对比应答的序号,如果发现是旧的报文就会给服务器发RST包,直至正确的SYN包到达服务器后才正常建立连接。 - 原因四:安全问题。
TCP 新建连接时内核会为连接分配一系列内存资源,如果采用两次握手可能会放大DDOS 攻击。
三次握手可以携带数据吗?
第一次握手和第二次握手不可以携带数据,第三次握手可以携带数据。假如第一次握手携带数据,如果碰到恶意攻击,那么每次在第一次握手的 SYN 报文中都会加入大量数据,会造成服务器花费大量存储空间来缓存这些数据。
为什么释放连接是四次,比建立连接多一次?
建立连接时服务器的 SYN 和 ACK 是合并发送的,而因 TCP 是全双工通信,释放连接过程中在客户端发送 FIN 包后,服务器可能还有数据需要发送,不能立即关闭连接,所以不能同时发送 FIN 包和 ACK 包,只能先确认 ACK,然后等服务器无数据发送时再发送 FIN 包。
为什么 TIME_WAIT 状态需要经过 2MSL 才能返回到 CLOSED 状态?
MSL 是指报文在网络中的最大生存时间。
- 原因一:在客户端回复服务器
FIN包的确认包ACK后,这个ACK包可能是不可达的,如果服务器收不到ACK的话需要重新发送FIN包。所以客户端发送ACK后需要留出2MSL时间(ACK到达服务器的时间 + 服务器重发FIN包时间),如果客户端等到2MSL后没有收到服务器重传的FIN包,说明可以确认服务器已经收到了客户端发送的ACK包。 - 原因二:客户端发送完最后一个
ACK包后,再经过2MSL时间就可以使当前连接持续的时间内所产生的所有报文都从网络中小时,使下一个新的连接中不会出现这种旧的连接请求报文。
相关文章:
TCP 建链(三次握手)和断链(四次握手)
TCP 建链(三次握手)和断链(四次挥手) 背景简介建链(三次握手)断链(四次挥手)序号及标志位延伸问题为什么建立连接需要握手三次,两次行不行?三次握手可以携带数…...
SpringBoot集成JOOQ加Mybatis-plus使用@Slf4j日志
遇到个问题记录下,就是SpringBoot使用Mybatis和Mybatis-plus时可以正常打印日志,但是JOOQ的操作日志确打印不出来? 下面的解决方法就是将JOOQ的日志单独配置出来,直接给你们配置吧! 在项目的resources目录下创建日志…...
浅谈JavaScript中的对象赋值
目录 常见的对象赋值方式 直接赋值和对象扩展(浅拷贝)两种赋值方式区别 区别 联系 常见的对象赋值方式 1. 直接赋值:this.info this.deviceInfo,将一个对象的引用赋给另一个变量,它们引用同一个对象。 2. 对象扩…...
Java面试题-集合
Java面试题-集合 1、什么是集合?2、集合和数组的区别是什么?3、集合有哪些特点?4、常用的集合类有哪些?5、List, Set, Map三者的区别?6、说说集合框架底层数据结构?7、线程安全的集合…...
从当当网批量获取图书信息
爬取当当网图书数据并保存到本地,使用request、lxml的etree模块、pandas保存数据为excel到本地。 爬取网页的url为: http://search.dangdang.com/?key{}&actinput&page_index{} 其中key为搜索关键字,page_index为页码。 爬取的数据…...
python爬虫之JS逆向——网页数据解析
目录 一、正则 1 正则基础 元字符 基本使用 通配符: . 字符集: [] 重复 位置 管道符和括号 转义符 转义功能 转义元字符 2 正则进阶 元字符组合(常用) 模式修正符 re模块的方法 有名分组 compile编译 二、bs4 1 四种对象 2 导航文档树 嵌套选择 子节点、…...
VL53L4CX TOF开发(2)----修改测距范围及测量频率
VL53L4CX TOF开发.2--修改测距范围及测量频率 概述视频教学样品申请完整代码下载测距范围测量频率硬件准备技术规格系统框图应用示意图生成STM32CUBEMX选择MCU串口配置IIC配置 XSHUTGPIO1X-CUBE-TOF1app_tof.c详细解释测量频率修改修改测距范围 概述 最近在弄ST和瑞萨RA的课程…...
C++之noexcept
目录 1.概述 2.noexcept作为说明符 3.noexcept作为运算符 4.传统throw与noexcept比较 5.原理剖析 6.总结 1.概述 在C中,noexcept是一个关键字,用于指定函数不会抛出异常。如果函数保证不会抛出异常,编译器可以进行更多优化,…...
Kafka之Broker原理
1. 日志数据的存储 1.1 Partition 1. 为了实现横向扩展,把不同的数据存放在不同的 Broker 上,同时降低单台服务器的访问压力,我们把一个Topic 中的数据分隔成多个 Partition 2. 每个 Partition 中的消息是有序的,顺序写入&#x…...
RabbitMQ docker安装及使用
1. docker安装RabbitMQ docker下载及配置环境 docker pull rabbitmq:management # 创建用于挂载的目录 mkdir -p /home/docker/rabbitmq/{data,conf,log} # 创建完成之后要对所创建文件授权权限,都设置成777 否则在启动容器的时候容易失败 chmod -R 777 /home/doc…...
篇3:Mapbox Style Specification
接《篇2:Mapbox Style Specification》,继续解读Mapbox Style Specification。 目录 Spec Reference Root 附录: MapBox Terrain-RGB...
C#WPF数字大屏项目实战11--质量控制
1、区域划分 2、区域布局 3、视图模型 4、控件绑定 5、运行效果 走过路过,不要错过,欢迎点赞,收藏,转载,复制,抄袭,留言,动动你的金手指,财务自由...
第九十七节 Java面向对象设计 - Java Object.Finalize方法
Java面向对象设计 - Java Object.Finalize方法 Java提供了一种在对象即将被销毁时执行资源释放的方法。 在Java中,我们创建对象,但是我们不能销毁对象。 JVM运行一个称为垃圾收集器的低优先级特殊任务来销毁不再引用的所有对象。 垃圾回收器给我们一个…...
【scikit-learn009】异常检测系列:单类支持向量机(OC-SVM)实战总结(看这篇就够了,已更新)
1.一直以来想写下机器学习训练AI算法的系列文章,作为较火的机器学习框架,也是日常项目开发中常用的一款工具,最近刚好挤时间梳理、总结下这块儿的知识体系。 2.熟悉、梳理、总结下scikit-learn框架OCSVM模型相关知识体系。 3.欢迎批评指正,欢迎互三,跪谢一键三连! 4.欢迎…...
网络管理与运维
文章目录 网络管理与运维概念:传统网络管理:基于SNMP集中管理:基于iMaster NCE的网络管理:传统网络管理方式: 基于SNMP集中管理:交互方式:MIB:版本:SNMPv3配置网管平台&a…...
数据库查询字段在哪个数据表中
问题的提出 当DBA运维多个数据库以及多个数据表的时候,联合查询是必不可少的。则数据表的字段名称是需要知道在哪些数据表中存在的。故如下指令,可能会帮助到你: 问题的处理 查找sysinfo这个字段名称都存在哪个数据库中的哪个数据表 SELEC…...
第 400 场 LeetCode 周赛题解
A 候诊室中的最少椅子数 计数:记录室内顾客数,每次顾客进入时,计数器1,顾客离开时,计数器-1 class Solution {public:int minimumChairs(string s) {int res 0;int cnt 0;for (auto c : s) {if (c E)res max(res, …...
数据结构与算法之Floyd弗洛伊德算法求最短路径
目录 前言 Floyd弗洛伊德算法 定义 步骤 一、初始化 二、添加中间点 三、迭代 四、得出结果 时间复杂度 代码实现 结束语 前言 今天是坚持写博客的第18天,希望可以继续坚持在写博客的路上走下去。我们今天来看看数据结构与算法当中的弗洛伊德算法。 Flo…...
Ubuntu系统设置Redis与MySQL登录密码
Ubuntu系统设置Redis与MySQL登录密码 在Ubuntu 20.04系统中配置Redis和MySQL的密码,您需要分别对两个服务进行配置。以下是详细步骤: 配置Redis密码 打开Redis配置文件: Redis的配置文件通常位于/etc/redis/redis.conf。 sudo nano /etc/redis/redis.c…...
数据库连接池的概念和原理
目录 一、什么是数据库连接池 二、数据库连接池的工作原理 1.初始化阶段: 2.获取连接: 3.使用连接: 4.管理和优化: 三、数据库连接池的好处 一、什么是数据库连接池 数据库连接池(Database Connection Pooling&…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型
CVPR 2025 | MIMO:支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题:MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者:Yanyuan Chen, Dexuan Xu, Yu Hu…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
