【TCP】三次握手 与 四次挥手 详解
三次握手 与 四次挥手
- 1. 三次握手
- 2. 四次挥手
- 三次握手和四次挥手的区别
在正常情况下,TCP 要经过三次握手建立连接,四次挥手断开连接
1. 三次握手
服务端状态转化:
- [CLOSED -> LISTEN]
服务器端调用 listen 后进入 LISTEN 状态,等待客户端连接; - [LISTEN -> SYN_RCVD]
一旦监听到连接请求(同步报文段 SYN),就将该连接放入内核等待队列中,并向客户端发送 SYN + ACK 确认报文。 - [SYN_RCVD -> ESTABLISHED]
服务端一旦收到客户端的确认报文 ACK,就进入 ESTABLISHED 状态,可以进行读写数据了。
客户端状态转化:
- [CLOSED -> SYN_SENT]
客户端调用 connect,发送同步报文段 SYN; - [SYN_SENT -> ESTABLISHED]
connect 调用成功,收到服务器的 SYN + ACK 报文段则进入 ESTABLISHED 状态,开始读写数据;
三次握手有啥用 ? 和可靠性有什么关系 ?
- 三次握手相当于 “投石问路”, 检查一下当前这个网络的情况是否满足可靠传输的条件。
如果网络本身效果比较差,强行进行 TCP 传输,也会涉及到大量的数据丢包,更具体的说,三次握手是在检测通信双方的发送能力和接收能力是否都正常。 - 让通信双方能协商一些必要的信息,TCP 通信过程中,需要客户端和服务器之间有一些共同的信息,在三次握手过程中相互之间可以交互一些必要的内容。
举个栗子:
以打电话为例, 这个过程就是在检验通信双方的发送能力和接收能力:
假如说小明麦克风坏了,喂了几次没回应,就会重传,重试几次还没回应就放弃。
为啥是三次握手,两次行不行? 四次行不行 ?
- 四次?行,但是没必要,分开传输不如合在一起效率高。
- 两次 ?不行!两次,意味着缺少最后一次
- 由上面的两张图就可以知道,两次的话,此时客户端知道双方的发送和接收能力都是正常的
- 但是服务器这边是残缺的,不知道自己的发送能力和客户端的接收能力是否 OK
- 此时服务器对于当下能否满足可靠传输心里没底
- 这第三次交互就是为了给服务器吃一个定心丸。
2. 四次挥手
服务端状态转化:
- [ESTABLISHED -> CLOSE_WAIT]
当客户端主动关闭连接(调用 close),服务器会收到结束报文段 FIN ,服务器返回确认报文段 ACK 并进入 CLOSE_WAIT; - [CLOSE_WAIT -> LAST_ACK]
进入 CLOSE_WAIT 后说明服务器准备关闭连接(需要处理完之前的数据);当服务器真正调用 close (用户代码中执行了 socket.close) 关闭连接时,会向客户端发送 FIN,此时服务器进入 LAST_ACK 状态,等待最后一个 ACK 到来(这个 ACK 是客户端确认收到了 FIN ) - [LAST_ACK -> CLOSED]
服务器收到了对 FIN 的 ACK,彻底关闭连接。
客户端状态转化:
- [ESTABLISHED -> FIN_WAIT_1]
客户端主动调用 close 时,向服务器发送结束报文段,同时进入 FIN_WAIT_1; - [FIN_WAIT_1 -> FIN_WAIT_2]
客户端收到服务器对结束报文段的确认 ACK,则进入 FIN_WAIT_2,开始等待服务器的结束报文段; - [FIN_WAIT_2 -> TIME_WAIT]
客户端收到服务器发来的结束报文段 FIN,进入 TIME_WAIT,并发出 LAST_ACK; - [TIME_WAIT -> CLOSED]
客户端要等待一个 2MSL(Max Segment Life,报文最大生存时间)的时间,才会进入 CLOSED 状态。
为什么还要 TIME_WAIT ?
为的是给最后一次 ACK 提供重传机会,表面上 A 发送完 ACK 后就没有 A 的事了,按理说 A 可以销毁连接了,但是怕最后一个 ACK 丢包,若最后一个 ACK 丢了,那么 B 一定会因为没收到 ACK 重传 FIN,如果 A 已经销毁连接了,那么就无人能够处理这个 FIN 了,因此 A 不应该释放的太早,要等待一段时间,确保 B 不会重传 FIN 后再真正的销毁连接。
为什么是TIME_WAIT的时间是2MSL?
MSL 是 TCP 报文的最大生存时间,因此 TIME_WAIT 持续存在 2MSL 的话
-
就能保证在两个传输方向上的尚未被接收或迟到的报文段都已经消失
(否则立刻客户端立即重新创建连接时,可能会收到来自上一个进程的迟到的数据(FIN),但是这种数据很可能是错误的);
-
同时也是在理论上保证最后一个报文可靠到达
(假设最后一个ACK丢失,那么服务器会再重发一个FIN。这时虽然客户端的进程不在了,但是 TCP 连接还在,仍然可以重发 LAST_ACK );
CLOSE_WAIT
一般而言,对于服务器上出现大量的 CLOSE_WAIT 状态,原因就是服务器没有正确的关闭 socket,没有执行到 socket.close 导致四次挥手没有正确完成。这是一个 BUG。只需要加上对应的 close 即可解决问题。
三次握手和四次挥手的区别
-
三次握手一定是客户端发起的(主动发起请求的一方叫做客户端)
四次握手可能是客户端发起的,也有可能是服务器主动发起的 -
三次握手,中间有两次合并和,
四次握手,中间两次合并不了,不能合并的原因在于 B (被动接收 FIN 的那一方)发送 ACK 和 FIN 的时机不同,
<1> 四次挥手中,B 发送给 A 的 ACK 是由操作系统内核负责的(除了应用层,TCP/IP … 本身就是属于操作系统层面),那么意味着,当内核收到 FIN 后会立即返回 ACK (我们是感知不到的)
<2> B 发送给 A 的 FIN,是由用户代码负责的,B 中代码调用了 socket.close() 方法时才触发 FIN 发送,所以要等到用户代码执行到 socket.close() 方法才触发,但是什么时候发送 取决于用户代码,若 <1> <2> 操作之间的时间差较大,就不能合并了,若时间差较小,由于 延时应带和捎带应答 机制,可能会合并。
而三次握手中 B 发送的 ACK 和 SYN 都是由内核负责的,是同一时机所以能够合并。
好啦! 以上就是对 TCP 三次握手 与 四次挥手的讲解,希望能帮到你 !
评论区欢迎指正 !
相关文章:

【TCP】三次握手 与 四次挥手 详解
三次握手 与 四次挥手 1. 三次握手2. 四次挥手三次握手和四次挥手的区别 在正常情况下,TCP 要经过三次握手建立连接,四次挥手断开连接 1. 三次握手 服务端状态转化: [CLOSED -> LISTEN] 服务器端调用 listen 后进入 LISTEN 状态ÿ…...

正则表达式新解
文章目录 是什么?正则用法匹配单个字符匹配一组字符其他元字符核心函数 贪婪匹配和非贪婪匹配正则练习 是什么? 正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊…...

MissionPlanner编译过程
环境 windows 10 mission planner 1.3.80 visual studio 2022 git 2.22.0 下载源码 (已配置git和ssh) 从github上克隆源码 git clone gitgithub.com:ArduPilot/MissionPlanner.git进入根目录 cd MissionPlanner在根目录下的ExtLibs文件下是链接的其它github源码࿰…...

SpringBoot 员工管理---通用模板 ---苍穹外卖day2
感谢点击 希望你有所收获! 目录 1.新增员工 需求分析:根据页面原型进行业务分析 接口设计 数据库设计 代码开发 功能测试 如何在接口文档中统一添加JWT令牌 获取当前登录员工的ID 2.员工分页查询 需求分析 代码开发 如何将日期格式化 3.启用禁用员工 1.新…...

可信执行环境(Tee)入门综述
SoK: Hardware-supported Trusted Execution Environments [ArXiv22] 摘要引言贡献 范围系统和威胁模型系统模型威胁模型共存飞地对手无特权软件对手系统软件对手启动对手外围对手结构对手侵入性对手 关于侧信道攻击的一点注记 VERIFIABLE LAUNCH信任根(RTM…...
Java浮点运算为什么不精确
有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准https://blog.zysicyj.top 首发博客地址[1] 面试题手册[2] 系列文章地址[3] 1. 什么是 Java 浮点运算? 在 Java 中,浮点运算指的是对浮点数进行加减乘除等基本运算…...

linux使用操作[1]
文章目录 版权声明快捷键ctrl c 强制停止ctrl d 退出、登出history命令光标移动快捷键清屏快捷键 软件安装命令常见linux系统包管理器yum命令apt命令 systemctl命令软连接日期&时区修改linux时区ntp程序 IP地址&主机名ip&主机名域名解析win配置主机名映射虚拟机…...

权限提升Linux篇
提权工具 https://github.com/liamg/traitor https://github.com/AlessandroZ/BeRoot https://github.com/rebootuser/LinEnum https://github.com/mzet-/linux-exploit-suggester https://github.com/sleventyeleven/linuxprivchecker https://github.com/jondonas/linux…...

影刀自动化采集底层逻辑
hello,大家好,这里是【玩数据的诡途】 接上回 <我的影刀故事> 今天给大家介绍一下整个采集的底层逻辑,包括业务流程自动化也是基于这一套基础逻辑进行展开的,顺便带大家熟悉一下影刀,既然叫影刀系列了,那后续一些…...

swiper使用
介绍 Swiper(swiper master)是一个第三方的库,可以用来实现移动端、pc端的滑动操作。,swiper应用广泛,使用频率仅次于jquery, 轮播图类排名第一,是网页设计师必备技能,众多耳熟能详的品牌在使用…...

基于遗传算法解决的多仓库多旅行推销员问题(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

微信小程序 工具使用(HBuilderX)
微信小程序 工具使用:HBuilderX 一 HBuilderX 的下载二 工具的配置2.1 工具 --> 设置 --> 运行配置2.1.1 微信开发者工具路径2.1.2 node 运行配置 2.2 插件 工具 --> 插件安装2.2.1 下载插件 三 微信小程序端四 同步运行五 BUG5.1 nodemon在终端无法识别 一 HBuilderX…...
设计模式:观察者模式(C++实现)
观察者模式(Observer Pattern)是一种设计模式,用于定义对象之间的一对多依赖关系,当一个对象(称为主题或可观察者)的状态发生变化时,它的所有依赖对象(称为观察者)都会收…...
【前端打怪升级日志之微前端框架篇】微前端qiankun框架子应用间跳转方法
参考链接qiankun官网:微应用之间如何跳转? 1.主应用、子应用路由都是hash模式 主应用根据 hash 来判断微应用,无需考虑该问题 2.主应用根据path判断子应用 方法实现适用条件参数传递存在问题a标签跳转<a href"/toA"></…...
C语言中的typedef struct用法
在学习数据结构的时候,我经常遇到typedef struct,刚开始感觉很别扭,查阅资料之后才真真理解了。 先从结构体说起。 1、结构体用法 struct Student{int age;char s;}如果要定义一个该结构体变量,就需要:struct Student st1; 有没…...
司徒理财:9.27黄金原油日内多空走势行情操作建议
黄金走势分析: 黄金昨日抵达了此前一直强调的日线布林下轨的1903位置,甚至更低!昨天的空单也是直接获利收割了!现在如果是要继续做空,下方是有日线支撑的,甚至周线的支撑也不远,在1890…...
C++设计模式(Design Patterns)
设计模式主要原则 单一职责原则(Single Responsibility Principle) 实现类要职责单一 里氏替换原则(Liskov Substitution Principle) 不要破坏继承关系 依赖倒置原则(Dependence Inversion Principle) …...

vue点击按钮收缩菜单
问题描述 VUE菜单有一个BUG,当我们点击其它按钮或者首页的时候,已经展示的一级菜单是不会自动收缩的。这个问题也导致很多开发者把一级菜单都换成了二级菜单。 错误展示 错误的效果请看下图。 解决方法 1、寻找菜单文件 因为我使用的是ruoyi的前端框…...
Vue 防止忘记的命令
创建新项目 npm init vuelatest cd <项目名> npm install npm run dev 运行项目 yarn yarn serve 这里如果我用npm install 或者npm run serve会报错,但是新建项目用npm就不会,有大佬知道为什么吗...
APACHE NIFI学习之—RouteOnContent
RouteOnContent 描述: 通过正则表达式匹配输入数据流的内容,然后将输入数据流的副本路由到正则表达式相匹配的输出数据流。 正则表达式作为用户自定义的属性添加,并以该属性名称为输出连线,其值为正则表达式所匹配数据流内容。 当用户定义的属性支持属性表达式语言时,其结…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...

macOS 终端智能代理检测
🧠 终端智能代理检测:自动判断是否需要设置代理访问 GitHub 在开发中,使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新,例如: fatal: unable to access https://github.com/ohmyzsh/oh…...

《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...