TCP 三次握手和四次挥手
✏️作者:银河罐头
📋系列专栏:JavaEE
🌲“种一棵树最好的时间是十年前,其次是现在”
目录
- TCP 建立连接(三次握手)
- 为啥不能是 4 次?
- 为啥不能是 2 次?
- 三次握手的意义:
- TCP 断开连接(四次挥手)
- 为啥是 4 次?
- 1.CLOSE_WAIT
- 2.TIME_WAIT
TCP 的建立连接过程(三次握手)和断开连接过程(四次挥手)
TCP 建立连接(三次握手)
通信双方各自要记录对方的信息,彼此之间要相互认同。
举个栗子:

这个过程中的每次通信,都称为是一次"握手"(形象的比喻)
上面的例子中进行了4 次交互,但是其中有 2 次可以合并成 1 次。

总结:所谓的三次握手,本质上是四次交互。通信双方各自向对方发起一个建立连接的请求,然后再各自向对方回应一个 ack。这里其实是有 4 次信息交互,但是其中有 2 次交互是可以合并成 1 次交互的。因此就构成了三次握手。
为啥不能是 4 次?
- 为啥要把中间这 2 次合并?不合并行嘛?
必须合并!
封装分用 2 次一定比封装分用 1 次,成本更高。
举个栗子:
我想在淘宝上买 3 样东西
假设我是在一个淘宝店铺下单的,通过多个订单来买的,此时店家是通过 3 个快递发给我?还是 1 个快递直接发了?分 3 次发,3 次包装成本,3 次快递费;1 次发了,1 次快递成本,1 次快递费。
为啥不能是 2 次?
- 如果是 2 次握手,能否完成建立连接的过程?
不行!(无法完全验证双方的发送和接收能力)
除了,通信双方要彼此认同之外,三次握手还有别的作用。
三次握手另外一个重要作用:验证通信双方各自的发送能力和接收能力是否正常。
三次握手也是一定程度的保证了 TCP 传输的可靠性。(起的是辅助作用)
举个例子:
张三和李四打游戏开黑,需要连麦

第一次交互:
当李四听到"听得到嘛",
李四就知道了:
1.张三的麦克风 ok
2.李四的耳机 ok
张三知道了:
(空)
第二次交互:
当张三听到"能听到",
张三就知道了:
1.张三的耳机 ok
2.李四的麦克风 ok
建立在第一次通信的基础上,
3.张三的麦克风 ok
4.李四的耳机 ok第三次交互:
李四听到"好了"意味着第二次通信李四说的"能听到"张三已经接收了
李四就知道了:
1.李四的麦克风 ok2.张三的耳机 ok
此时,双方都知道了彼此的麦克风和耳机都是 ok 的
连接,包含连接的建立,断开和维护,三次握手只是建立这个环节。
“有连接”
1.需要连接先建立好,才能进行通信
2.如果连接断开了,此时就无法进行通信了。
3.连接建立过程中,通信双方要保存好对方的信息。
有没有连接和是否确认应答 没有任何关系。
确认应答体现的是可靠传输,可靠传输和有连接是不相关的。
无连接,也可以可靠传输。eg:飞书/钉钉/企业微信,发个消息不需要建立连接,直接就能发,发个消息有个"已读"状态,这就相当于 ack
三次握手的意义:
1.让通信双方各自建立对对方的"认同"。
2.验证通信双方各自的发送能力和接收能力是否 ok.
3.在握手的过程中,双方来协调一些重要的参数。(比如 TCP 的序号不一定是从 1 开始编号的,双方协商从哪个数字开始编号)
TCP 通信过程中,有些数据通信双方要相互同步,此时就需要有这样的交互过程,恰好可以利用三次握手的机会,来完成数据的同步。

客户端主动给服务器发起"建立连接请求",称为"syn",同步报文段
建立连接阶段,主要认识 2 个状态
1.LISTEN 服务器的状态
表示服务器已经准备就绪,随时可以有客户端来建立连接。(相当于手机开机,信号良好,随时可以有人来打电话)
2.ESTABLISHED 客户端和服务器都有的状态
连接建立完成,接下来可以进行通信了。(相当于电话打过去,对方接通了)
TCP 断开连接(四次挥手)
"挥手"和"握手"都是客户端服务器之间的数据交互。
四次挥手和三次握手非常类似。通信双方给对方发起"断开连接请求",然后再各自给对方一个回应。

为啥是 4 次?
- 在断开连接过程中,中间两次,通常情况下不能合并(特殊情况下可以)
两个数据发送的时机相同才能合并,不同就不能合并。
举个栗子:
我要在淘宝上买 3 样东西。
从同一个店铺买。如果这 3 个订单是同一时间下的,此时就可以一个包裹发过来,
如果是分开下的呢?
如果是今天买了 A,过了一周买了 B,再过一个月买了 C。此时就只能分成多个包裹发货了。
三次握手的中间 2 次能够合并,是因为他俩是同一时机。具体来说,三次握手 这 3 次交互过程是纯内核完成的(应用程序感知不到,也干预不了)
服务器的系统内核收到 syn 之后,就会立即发送 ack ,也会立即发送 syn

FIN 的发起,不是由内核控制的,而是由应用程序调用 socket 的 close 方法(或者进程退出),才会触发 FIN。
ACK 是由内核控制的,是收到 FIN 之后,立即返回 ACK
所以第 2 步的 ACK 和第 3 步的 FIN ,这两者之间就会隔了一个时间差,这个时间是长是短得看具体代码的实现。
之前写过的 TcpEchoServer 代码:




四次挥手中涉及到的 2 个重要的 TCP 状态
1.CLOSE_WAIT
出现在被动发起断开连接的一方。
建立连接一定是客户端主动发起请求;而断开连接有可能是客户端主动发起,也可能是服务器主动发起。
举个栗子:
谈恋爱追人的时候一般是男生主动。但是分手的时候可以是男生提分手也可以是女生提分手
等待关闭(等待调用 close 方法关闭 socket)
收到 FIN 并立即返回 ACK 之后状态就设置成 CLOSE_WAIT,下一步就应该轮到应用程序调用 close 完成后续的 2 次挥手。
2.TIME_WAIT
出现在主动断开连接的一方。
假设是客户端主动断开连接,当客户端收到 第 3 次 FIN 并 返回第 4 次 ACK 之后 TCP 就进入 TIME_WAIT 状态。
此时相当于 4 次挥手都挥完了。
此时这里的 TIME_WAIT 要保持 当前的 TCP 连接状态不要立刻就释放。
- 为啥不要立即释放,为啥要以 TIME_WAIT 保留一会儿连接?
最后这个 ACK 才刚发出去,对方还没有收到呢,万一丢包了呢。
在三次握手和四次挥手的过程中也是同样存在"超时重传"的。
如果最后一个 ACK 丢包了,站在服务器的视角来看,服务器不知道是因为 ACK 丢了还是自己发的 FIN 丢了,所以统一视为 FIN 丢了,统一进行重传操作。
既然服务器可能会重传 FIN,客户端就需要针对这个重传的 FIN 进行 ACK 响应。如果刚才把连接彻底释放了这样的话 ACK 就没办法进行了。
因此使用 TIME_WAIT 状态保留一段时间,就是为了能够处理最后一个 ACK 丢包的情况,能够在收到重传的 FIN 进行 ACK 响应。
TIME_WAIT 会等,如果等了一段时间也没有收到这个重传的 FIN,此时就认为 最后一个 ACK 没丢,此时就彻底断开连接了。
- TIME_WAIT 具体保持多长时间就真正释放呢?
约定一个时间,2 MSL
MSL 指的是互联网上,两个结点之间,数据传输消耗的最大时间。
MSL 具体是几?
通常情况下这个值是 60 s
MSL 相当于是一个经验值。按照一般的经验来说,绝大部分数据报传输的时间都不会超过 MSL
如果经历了 2 MSL 还没有收到重传的 FIN,此时就认为最后一个 ACK 成功到达了(认为对方没有重传 FIN)

- 是每个状态都等 2 MSL 吗?
TIME_WAIT 才是等这个时间,其他的交互过程都是跟着超时重传的时间阈值走的
相关文章:
TCP 三次握手和四次挥手
✏️作者:银河罐头 📋系列专栏:JavaEE 🌲“种一棵树最好的时间是十年前,其次是现在” 目录TCP 建立连接(三次握手)为啥不能是 4 次?为啥不能是 2 次?三次握手的意义:TCP 断开连接(四…...
JavaWeb复习
JavaWeb复习一.概述1.概念2.B/S和C/S 架构二.HTTP通信协议概述1.概念2.HTTP1.0 与 HTTP1.1 版本3.HTTP 协议组成4.常见状态码5.GET 与 POST 请求方式三.Tomcat1.Web服务器介绍2.安装(Windows)3.Tomcat目录结构4.server.xml部分配置解释四.Servlet1.概念2…...
P14 PyTorch AutoGrad
前言:激活函数与loss的梯度PyTorch 提供了Auto Grad 功能,这里系统讲解一下torch.autograd.grad系统的工作原理,了解graph 结构目录:1: require_grad False2: require_grad True3: 多层bakcward 原理4: in…...
前端报表如何实现无预览打印解决方案或静默打印
在前端开发中,除了将数据呈现后,我们往往需要为用户提供,打印,导出等能力,导出是为了存档或是二次分析,而打印则因为很多单据需要打印出来作为主要的单据来进行下一环节的票据支撑, 而前端打印可…...
Operating System Course 2 - My OS
Computer Startup process上一篇:http://t.csdn.cn/XfUKt 讲到这个启动设备的第一个扇区:引导扇区。那么引导扇区的代码长什么样子?这里得看引导扇区代码源文件bootsect.s(.s后缀文件为用汇编语言编写的源代码文件)。另…...
离散数学 课时一 命题逻辑的基本概念
1 命题 1、命题:可以判断其真值的陈述句 2、真值:真或者假(1或者0) 3、真命题:真值为真的命题 4、假命题:真值为假的命题 5、原子命题:不可以再被分解成更简单的命题 6、复合命题:由原子命题通过联结词联结…...
Word文档带有权限密码怎么办?
Word文档的权限密码指的是什么?其实这是Word文档的保护方法之一,具体指Word文档的编辑、修改受到了限制,需要输入密码才能进行。 设置了权限密码的Word文档还是可以直接打开,只有当需要编辑或者修改内容的时候,才会发…...
C++多态
1. 多态的概念1.1 概念多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状态举个例子:比如买票这个行为,当普通人买票时,是全价买票;…...
访问学者如何申请美国J1签证?
一、申请美国J1签证的步骤: 第一步:填写I901表。 填写I901表会收取SERVIS费用180美元,可以用VISA/Master卡直接网上支付。填完后打印收据单或者存成PDF后续再打印,记下I901收据编号。 第二步:DS-160表填写。 填写DS-…...
使用gitlab ci/cd来发布一个.net 项目
gitlab runner的安装和基本使用:https://bear-coding.blog.csdn.net/article/details/120591711安装并给项目配置完gitlab runner后再操作后面步骤。实现目标:master分支代码有变更的时候自动构建build。当开发人员在gitlab上给项目打一个tag标签分支的时候自动触发…...
笔试题-2023-蔚来-数字芯片设计【纯净题目版】
回到首页:2023 数字IC设计秋招复盘——数十家公司笔试题、面试实录 推荐内容:数字IC设计学习比较实用的资料推荐 题目背景 笔试时间:2022.08.24应聘岗位:校招-芯片逻辑综合工程师-智能硬件笔试时长:90min笔试平台:nowcoder牛客网题目类型:不定项选择题(15道)、填空题…...
ThreadLocal 详解
ThreadLocal简介JDK源码对ThreadLocal类的注释如下:ThreadLocal提供线程局部变量,使得每个线程都有自己的、独立初始化的变量副本ThreadLocal实例通常是类中的private static字段,用于将状态与线程相关联,如用户ID、事务ID只要线程…...
【Java 面试合集】重写以及重载有什么区别能简单说说嘛
重写以及重载有什么区别能简单说说嘛 前述 这是一道非常基础的面试题,我们在回答的过程中一定要逐一横向比较。 从方法的 修饰符,返回值,方法名,含义,参数等方面进行逐一分析来比较不同。 话不多话,看下…...
到底什么是股票委托接口?
在量化股票市场上,常见的股票委托接口其实有着不一样的交集,就拿股票交易接口,在量化股票跟程序化交易中,有共同之处就是在于直接委托执行下单,并且能很快的就能够将策略输出在账户持仓数据中,继续缓存下来…...
Linux驱动:VPU
1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. 概述 VPU 是用来进行图像、视频数据进行硬件编、解码的硬件模块。内部集成了 Encoder、Decoder 功能部件进行图像、视频数据进行硬件编、解码&a…...
简介Servlet
目录 一、maven中心库 二、简介Servlet 三、实现Servlet动态页面 1、创建一个maven项目 2、引入依赖 3、创建目录结构 4、编写Servlet代码 5、打包 6、部署 7、验证程序 四、Servlet的运行原理 五、Tomcat伪代码 1、Tomcat初始化 a、让Tomcat先从指定的目录…...
Learning C++ No.7
引言: 北京时间:20223/2/9/22:20,距离大一下学期开学还有2天,昨天收到好消息,开学不要考试了,我并不是害怕考试,考试在我心里,地位不高,可能只有当我挂了,才能…...
【MyBatis】第八篇:一级,二级缓存
其实缓存字面的意思就是将一些内容缓存下来,等下次使用的时候可以直接调用,通过数据库得到数据,有时候会使用相同的数据,所以mybatis自然也支持缓存。 而mybatis按照缓存的效果可以分两大类:一级缓存和二级缓存。 一…...
【大唐杯备考】——5G基站开通与调测(学习笔记)
📖 前言:本期介绍5G基站开通与调测。 目录🕒 1. 概述🕒 2. 5G基站开通与调测基础🕘 2.1 3.5GHz单模100MHz配置(S111)🕘 2.2 3.5GHz单模100MHz配置(S111111)&a…...
redhat7 忘记root密码,重置办法
来自https://www.tracymc.cn/archives/802 亲测可用,太感谢了,在此记录一下,原文有图 1.启动的时候,在有启动项界面,相应启动项内核名称上按“e”; 2.进入后,找到linux16开头的地方,按“end”键或者controle到最后,输入rd.break,再按ctrlx进…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案
问题描述:iview使用table 中type: "index",分页之后 ,索引还是从1开始,试过绑定后台返回数据的id, 这种方法可行,就是后台返回数据的每个页面id都不完全是按照从1开始的升序,因此百度了下,找到了…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
