【Linux C | 网络编程】详细介绍 “三次握手(建立连接)、四次挥手(终止连接)、TCP状态”
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍“三次握手(建立连接)、四次挥手(终止连接)、TCP状态” 🍭
😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭
本文未经允许,不得转发!!!
目录
- 🎄一、概述
- 🎄二、三次握手(建立连接)
- ✨2.1 三次握手的过程
- ✨2.2 为什么需要三次握手
- 🎄三、四次挥手(终止连接)
- ✨2.1 四次挥手的过程
- ✨2.2 为什么需要四次挥手
- 🎄四、TCP状态
- 🎄五、总结
🎄一、概述
一个TCP连接通常分为3个阶:建立连接、数据传输(也称作“连接已建立”)、终止连接。其中建立连接、终止连接就涉及到经常听到的三次握手,四次挥手
。并且,三次握手,四次挥手
常常出现在面试中,大部分应试者一上来就是知道回复:
首先,客户端向服务端发送一个"SYN"分节;
然后,服务端向客户端发送一个"SYN+ACK"分节
最后,客户端向服务端发送一个ACK分节表示确认
这样回答是生硬的、欠缺的、不够深度的。
那请问:
1、三次握手的目的是什么?
2、为什么需要三次握手?
3、两次握手行不行?
4、SYN报文可以携带数据吗?
5、三次握手过程中,每次发送报文后,TCP处于什么状态?
6、四次挥手的过程是怎样的?
7、为什么握手是三次,挥手却要四次?
8、什么是半关闭状态?
如果上面几个问题都懂了,那不必往下看了。
🎄二、三次握手(建立连接)
TCP协议一个面向连接的协议,那么这个连接是怎么建立的呢?
TCP的连接就是通过所谓的三次握手来建立的,在网络编程中,TCP连接的建立是发生在客户端的connect函数和服务端的accept函数中的。所以,我们常常可以看到使用套接字API写TCP客户端时,都是依次调用socket、connect
,而服务器常见的是依次调用socket、bind、listen、accept
。
✨2.1 三次握手的过程
建立一个TCP连接会进行下面步骤:
- 1、TCP客户端调用
socket
函数获取到套接字句柄之后,调用connect
函数发起主动打开
(active open),这将导致客户端TCP发送一个SYN报文段
(一个TCP头部的SYN位字段置位的TCP/IP数据包),并指明自己想要连接的端口号和它的客户端初始序列号
(Initial Sequence Number, ISN)。通常,客户端还会借此发送一个或多个选项。 - 2、TCP服务端在调用依次
socket、bind、listen
之后,执行被动打开
(passive open)。服务端接收到客户端的SYN报文后,也发送自已的SYN报文段作为响应,并包含了它的初始序列号
;此外,为了确认客户端的SYN,服务端将客户端的初始序列号
(Initial Sequence Number, ISN)数值加1后作为返回的ACK数值。 - 3、客户端为了确认服务器的SYN,将
服务端的初始序列号
(Initial Sequence Number, ISN)数值加1后作为返回的ACK数值。
经过上面三个步骤,TCP连接就建立成功了,之后可以通过read、write等函数交互数据了。
注意:三次握手是在传输层完成的,主要通过操作系统内核的网络协议栈来处理。connect仅仅是通知给linux内核,让linux内核自动完成TCP三次握手连接。
上面三路握手过程图中,看到客户端的SYN报文到达是,accept函数已经调用,容易错误地认为需要accept函数调用后,才可以建立三次握手。其实,只要服务端调用listen函数后就可以正常建立三次握手了,accept调不调用都不影响三次握手的建立,accept函数的作用是从服务端的已连接队列中获取一个已建立的连接,所以如果服务端需要与客户端通信就需要调用accept。
✨2.2 为什么需要三次握手
三次握手的目的不仅在于让通信双方了解一个连接正在建立,还在于利用数据包的选项来承载特殊的信息,交换初始序列号(Initial Sequence Number, ISN)。
另外,必须是三次握手后,才可以让客户端、服务端都确认对方的发送、接收能力是否正常:
- 第一次握手(
cli -> ser
):
客户端
检测服务端的接收能力。
服务端
收到客户端的SYN后,确认了客户端具有发送能力。 - 第二次握手(
ser -> cli
):
客户端
收到服务端的SYN+ACK,确认了服务端具有发送能力,同时说明服务端已经收到自己的SYN(具有接收能力);
服务端
检测客户端的接收能力。 - 第三次握手(
ser -> cli
):
服务端
收到客户端的ACK,说明客户端已经收到自己的SYN(具有接收能力)。
如果只有两次握手行不行呢?
只有两次握手的话,服务端消息发出去后,没受到响应,无法确认客户端是否可以接收信息。所以需要三次握手才可以建立连接。
注意:TCP的SYN段也能够承载应用数据。由于伯克利的套接字API不支持这种方式,因此它也很少为人所用
🎄三、四次挥手(终止连接)
TCP连接建立后,客户端、服务端会交互数据,最后连接的任一方可以发起终止,一般是客户端发起终止,但有些服务端处理完客户端的请求后也会发起关闭操作。
✨2.1 四次挥手的过程
- 1、TCP连接的任一端首先调用
close
或shutdown
函数,执行主动关闭
,这会向TCP连接对端发送一个FIN报文段
,并指明当前的序列号,该FIN段还包含了一个ACK段用于确认对方最近一次发来的数据。 - 2、接收到
FIN报文段
的一端执行被动关闭
,将发过来的序列号加1作为响应的ACK数值。上层的应用程序会接收到一个文件结束符(end-of-file)表示该连接不会再发送数据过来,read函数会返回0; - 3、一段时间后,接收到这个文件结束符的应用程序也会调用
close
或shutdown
函数关闭它的套接字,这会导致它的TCP也发送一个FIN报文段
。 - 4、接收到这个最后
FIN报文段
的一端会将接收到的序列号加1作为响应的ACK数值。
✨2.2 为什么需要四次挥手
为什么连接的时候是三次握手,终止的时候却是四次握手?
- 三次握手:因为服务端接收到SYN报文后,可以将确认的ACK数组添加到自己的SYN报文中一并发出。
- 四次挥手:因为TCP存在
半关闭状态
,就是允许连接的一端在结束它的发送后还能接收来自另一端数据。一般情况下,收到FIN报文
后,并不会立刻关闭socket,而是先回复一个ACK报文,因为此时可能还有一些数据正在发送,等所有数据发送后,才会发送FIN报文
,所以需要四次握手。但这并不是必然的,在《Unix网络编程卷1》有提到,第2、3步骤都出自执行被动关闭的那一端,可能被合成一个报文。
🎄四、TCP状态
TCP状态共11种:
- 1、 客户端独有的:(1)SYN_SENT (2)FIN_WAIT1 (3)FIN_WAIT2 (4)CLOSING (5)TIME_WAIT 。
- 2、服务端独有的:(1)LISTEN (2)SYN_RCVD (3)CLOSE_WAIT (4)LAST_ACK 。
- 3、共有的:(1)CLOSED (2)ESTABLISHED 。
LISTEN - 监听来自客户端的连接请求;
SYN_SENT - 在发送连接请求后等待响应的状态;
SYN_RCVD - 在收到和发送一个连接请求后等待对端确认的状态;
ESTABLISHED - 代表一个已建立的连接,数据开始交互;
FIN_WAIT1 - 主动关闭,发送完FIN,等待对端确认;
FIN_WAIT2 - 主动关闭,发送完FIN且已收到对端确认,等待接收FIN;
CLOSE_WAIT - 被动关闭,接收完FIN且已确认,等待发送FIN;
CLOSING - 发送完FIN后,还没收到ACK,就收到FIN并确认,说明对端也正在关闭,等待对端确认;
LAST_ACK - 被动关闭,发送完FIN,等待对端确认;
TIME-WAIT - 等待2MSL,以确保对端TCP接收到连接终止的确认;
CLOSED - 没有任何连接状态;
🎄五、总结
👉本文详细介绍了三次握手(建立连接)的过程、目的,以及四次挥手的过程、目的,最后讲解了TCP连接的11种状态。
如果真的面试遇到了三次握手、四次挥手的问题,建议这么做,
1、先把过程图画出来;
2、把三次握手、四次挥手的过程展开说一下,然后看情况,可以直接结束了,也可以再说说为什么需要三次握手、四次挥手;
3、最后,把最前面的几个问题都准备好,以防提问到。
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁
参考资料:
《Unix 网络编程卷1》
《TCP/IP 详解卷1》
《我终于搞懂了TCP的三次握手和四次挥手》https://blog.csdn.net/weixin_45393094/article/details/104965561
《面试官,不要再问我三次握手和四次挥手》https://blog.csdn.net/hyg0811/article/details/102366854
相关文章:

【Linux C | 网络编程】详细介绍 “三次握手(建立连接)、四次挥手(终止连接)、TCP状态”
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...

主从数据库MySQL服务重启步骤与注意事项
主从数据库MySQL服务重启步骤与注意事项 实验环境: 172.20.26.34 (主应用服务器) 172.20.26.26 (备应用服务器) 172.20.26.37 (主库服务器) 172.20.26.38 (从库服务器&…...

netlink学习
netlink是什么 netlink是Linux内核中的一种进程间通信(IPC)机制。它允许内核空间与用户空间之间,以及用户空间进程之间进行双向通信。 内核里的很多子系统使用netlink通信,包括网络管理(Routing,Netfilt…...

地理空间分析10——空间数据分析中的地理编码与Python
目录 写在开头1. 地理编码基础1.1 地理编码的基本原理1.1.1 坐标系统1.1.2 地名解析1.1.3 编码算法1.2 Python中使用地理编码的基础知识1.2.1 百度地图API1.2.2 高德地图API1.2.3 腾讯地图API1.3 Python中实现代码2. 逆地理编码2.1 利用Python进行逆地理编码2.1.1 获取高德地图…...

使用“快速开始”将数据传输到新的 iPhone 或 iPad
使用“快速开始”将数据传输到新的 iPhone 或 iPad 使用 iPhone 或 iPad 自动设置你的新 iOS 设备。 使用“快速开始”的过程会同时占用两台设备,因此请务必选择在几分钟内都不需要使用当前设备的时候进行设置。 确保你当前的设备已连接到无线局域网,并…...

计算机网络(第六版)复习提纲13
前同步码,七位1010交替出现,帧开始码:10101011 为什么没有帧结束?曼彻斯特码传播完成后,维持高电平,不再跳变,因此不必要设置帧结束。 3.无效的MAC帧 i.数据字段的长度与长度字段的值不一致&…...

[office] excel2010双向条形图制作 #经验分享#微信
excel2010双向条形图制作 本教程为大家介绍一下excel2010中excel2010双向条形图制作方法。 1.选中工作区域 2.点击插入-->图表,选择条形图 3.为美观可将中间竖线可去掉 4.方法是选中竖线,右击-->删除 5.接下来将图例靠上,选中图例,右击-->设置图例格式-->图例选项…...

优雅管理多线程异步任务 - 永动异步任务
引言 在现代应用程序中,经常需要处理长时间运行的异步任务,如消息推送、定时任务等。为了确保这些异步任务能够安全可靠地执行,我们需要一种优雅的管理方式。本文将介绍一种基于线程池的多线程异步任务管理方案,并详细讨论任务的优雅关闭。 1. 多线程异步任务管理的需求 …...

软考笔记--分布式数据库
分布式数据库系统是数据库技术与网络技术相结合的产物,其基本思想是将传统的集中式数据库中的数据分布于网络上的多台计算机中。分布式数据库系统通常使用较小的计算机系统,每台计算机可单独放在一个地方,每台计算机中都有DBMS的一份完整的复…...

vue项目中路由懒加载的三种方式
1 . vue异步组件技术 异步加载 vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 . 但是,这种情况下一个组件生成一个js文件 /* vue异步组件技术 */ { path: /home, name: home, component: resolve > require([/components/home],resolve) }, { path…...

【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏6(附项目源码)
本节最终效果演示 文章目录 本节最终效果演示系列目录前言生命 食物 水简单绘制UI玩家状态脚本生命值控制饱食度控制水分控制 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中…...

Cache Lab:Part A【模拟出使用LRU策略的高速缓存存储器组织结构】
目录 任务描述 知识回顾 实验内容 测试结果 Cache Lab 对应《CS:APP》6.3节至第六章结束的内容。 任务描述 Your job for Part A is to fill in the csim.c file so that it takes the same command line arguments and produces the identical output as the reference …...

操作系统基础:死锁
🌈个人主页:godspeed_lucip 🔥 系列专栏:OS从基础到进阶 🐦1 死锁的概念🦢1.1 总览🦢1.2 什么是死锁🦢1.3 死锁、饥饿、死循环的区别🐧1.3.1 概念🐧1.3.2 区别…...

Ubuntu server如何使用 Daphne + Nginx + supervisor部署 Django
Django从 3.0版开始加入对ASGI的支持,使Django开始具有异步功能。 截止目前的5.0版,对异步支持逐步也越来越好,相信在未来的版本中异步将会支持的更加完善。 所以说,我们也需要适时的更新我们的技能,学会在asgi异步服务器环境中部署django项目! 在部署之前我们所有的依…...

Android 12.0 应用中监听系统收到的通知
1. 需求 在系统内置应用中或者在第三方应用中,获取Android系统收到的通知的内容. 2. NotificationListenerService 接口 Android 系统预留了专门的API, 即 NotificationListenerService 接口,它的源码路径为: 源码路径 : /frameworks/base/core/java/android/service/notifi…...

SpringBoot+Redis如何实现用户输入错误密码后限制登录(含源码)
点击下载《SpringBootRedis如何实现用户输入错误密码后限制登录(含源码)》 1. 引言 在当今的网络环境中,保障用户账户的安全性是非常重要的。为了防止暴力破解和恶意攻击,我们需要在用户尝试登录失败一定次数后限制其登录。这不…...

kotlin中的初始化问题纪录
1. init 代码块的顺序问题 init代码块和成员变量实质上是按先后顺序执行的。若果init{} 中有成员变量使用。要把成员变量放到代码块之前。 2. init代码块之中的函数问题 下面是一段错误的代码: class mkotlin{val info:Stringinit {getInfoMethod()info "adad…...

Web中的转发与重定向
转发与重定向 一、转发和重定向的概念1.转发2.重定向 二、JavaWeb 中的转发和重定向三、SpringMVC 中的转发和重定向1.转发(1) 默认的方式(2) 完整的方式 2.重定向 四、总结 一、转发和重定向的概念 在 Web 应用中,转发和重定向都是用于将请求从一个页面传递到另一…...

交叉注意力融合时域、频域特征的FFT + CNN-Transformer-CrossAttention轴承故障识别模型
目录 往期精彩内容: 前言 1 快速傅里叶变换FFT原理介绍 第一步,导入部分数据 第二步,故障信号可视化 第三步,故障信号经过FFT可视化 2 轴承故障数据的预处理 2.1 导入数据 2.2 制作数据集和对应标签 3 交叉注意力机制 …...

STM32读取MPU6050数据并通过角度值控制舵机运动(STM32、GY-521 MPU6050、SG90舵机、MG946舵机)
通过STM32F103C8T6读取MPU6050数据控制舵机运动(STM32、GY-521 MPU6050、SG90舵机、MG946舵机) 最终现象一、MPU6050数据读取二、舵机控制原理①什么是PWM?②STM32F103C8T6如何生成PWM?③控制舵机需要什么样的PWM波? 三…...

Unity_Playable工具使用
Unity_Playable工具使用 目录 Unity_Playable工具使用 1. Default Playables(Timeline扩展) 2. PlayableGraph Visualizer&#x...

Flutter canvas 画一条波浪线 进度条
之前用 Flutter Canvas 画过一个三角三角形,html 的 Canvas 也画过一次类似的, 今天用 Flutter Canvas 试了下 感觉差不多: html 版本 大致效果如下: 思路和 html 实现的类似: 也就是找出点的位置,使用二阶…...

Java技术栈 —— Spring MVC 与 Spring Boot
参考文章或视频链接[1] Spring vs. Spring Boot vs. Spring MVC[2] Key Differences Between Spring vs Spring Boot vs Spring MVC...

跟着cherno手搓游戏引擎【16】Camera和Uniform变量的封装
相机封装: OrthographicCamera.h: #pragma once #include <glm/glm.hpp> namespace YOTO {class OrthographicCamera{public:OrthographicCamera(float left,float right , float bottom,float top);const glm::vec3& GetPosition()const { return m_Pos…...

微服务中间件 RabbitMq学习
1、为什么需要Mq 例如在用户注册业务中,用户注册成功后 需要发注册邮件和注册短信,传统的做法有两种 1.串行的方式;2.并行的方式 ; 假设三个业务节点分别使用50ms,串行方式使用时间150ms,并行使用时间10…...

3D Gaussian Splatting-实时辐射场渲染技术
引用自:https://repo-sam.inria.fr/fungraph/3d-gaussian-splatting/3d_gaussian_splatting_high.pdf 概述: 该论文介绍了一种用于实时辐射场渲染的3D高斯点渲染技术。 其基本原理是: 一:首先从SfM校准的图像及其对应的稀疏点云…...

vue中nextTick()
在 Vue.js 中,nextTick() 是一个非常有用的方法,用于在下一个 DOM 更新循环结束后执行延迟回调。这在你需要读取或写入刚刚更新的 DOM 时非常有用。 下面是一个简单的示例代码,用于解析 nextTick() 的用法: <template> &…...

Redis 布隆过滤器
布隆过滤器 这一篇文章主要是记录布隆过滤器的使用和认识 主要参考了如下的blog https://blog.csdn.net/weixin_42972832/article/details/131211665 他讲的还不错 简单的来说,布隆过滤器,实际上就像是一个集合,拿redis的key来举例来说,布隆过滤器的设置就是去过滤不属于redi…...

中国的茶文化:现代生活中的茶文化
中国的茶文化:现代生活中的茶文化 引言 在现代社会的快节奏生活中,茶文化并未随时间流逝而褪色,反而以其独特的方式融入了全球各地人们的日常生活。它超越了饮品本身的范畴,成为一种连接历史、人文与现代生活方式的艺术形式。本文…...

Python正则表达式语法
正则表达式是一种强大的文本处理工具,它可以用来搜索、匹配和替换特定的字符模式。在Python中,正则表达式常常被用于处理字符串数据,例如文本搜索、数据提取、格式验证等任务。本文将深入介绍Python中正则表达式的语法,帮助读者全…...