【通俗易懂】三次握手与四次挥手

article/2025/9/15 16:17:03

1.三次握手

三次握手(Three-way Handshake)是指在建立一个TCP连接时,客户端和服务器会一共发送三个报文段。

初始时客户端和服务器都处于CLOSED状态,当服务器应用程序创建一个监听套接字时,服务器处于LISTEN状态。

1.第一次握手:客户端向服务器发送一个SYN报文段,报文段的首部中的标志位SYN置为1,另外还会指明自己的初始化序号seq=x,此时客户端处于SYN_SENT状态。

2.第二次握手:服务器收到SYN的报文段后,会以自己的SYN-ACK报文进行应答。该应答报文的首部有三个重要信息:首先SYN被置为1;其次,确认号字段ack=x+1;最后服务器选择自己的初始序号seq=y。该报文段表明:“我收到了你发起建立连接的请求,该请求报文的初始序号是x(确认号ack=x+1就表明了我收到了初始序号seq=x的报文),我同意建立该连接,我的初始序号是y。”此时服务器处于SYN_RCVD状态。

3.第三次握手:客户端收到SYN-ACK报文后,会发送一个ACK报文段,该报文段中序号seq=x+1,确认号ack=y+1,表明我已经收到了你的确认。此时客户端处于ESTABLISHED状态。

服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,双方以建立起了链接。

需要注意的是:第一次握手和第二次握手都只是消耗掉一个序号,但不能携带数据;第三次握手可以携带数据

在这里插入图片描述

三次握手的作用?(为什么要进行三次握手?两次握手不行吗?)

1.1 三次握手的作用:

(1)确认双方的接受能力、发送能力是否正常。
(2)指定自己的初始化序列号,为后面的可靠传送做准备。

1.2 三次握手的目的是什么

第一次握手:客户端给服务器发送一个报文,告知服务器:“我客户端想和你建立连接”。

服务器收到第一段报文后得出结论:客户端发送功能正常,服务器接收功能正常。

第二次握手:服务器收到报文后给客户端回复一个报文,告知客户端:“我服务器收到了你的请求,同意和你建立连接”。

客户端收到第二段报文后得出结论:客户端发送和接收功能都正常,服务器的发送接收功能也都正常。(但此时服务器不能确认客户端的接收功能和自己的发送功能是否正常)。

第三次握手:客户端收到第二段报文后给服务器回复一个报文,告知服务器:“我客户端收到了你的回复,知道你同意连接,那我们开始连接吧!”

服务器收到第三段报文后得出结论:客户端的接收功能和服务器的发送功能也都正常。

所以当服务器收到第三个报文后,两边就建立起了TCP连接。

1.3 两次握手为什么不行?

那么两次握手为什么不行就显而易见了,只有前两次握手的话,服务器就不能确认自己回复的报文段是否被客户端接收到,也就不知道自己的发送功能和客户端的接收功能是否正常。

2.四次挥手

四次挥手也就是客户端与服务器断开连接时,需要一共发送四个报文段来完成断开TCP连接。

初始时,客户端与服务器都处于ESTABLISHED状态,假如客户端发起断开连接的请求(服务器也可以发起),四次挥手过程如下:

1.第一次挥手:客户端发送一个FIN报文段,报文段中指定序号seq=u。此时客户端处于FIN_WAIT_1状态。

2.第二次挥手:服务器收到FIN报文后,立即发送一个ACK报文段,确认号为ack=u+1,序号设为seq=v。表明已经收到了客户端的报文。此时服务器处于CLOSE_WAIT状态。

在第二次挥手和第三次挥手之间的时间段内,由于只是半关闭的状态,数据还是可以从服务器传送到客户端的。

3.第三次挥手:如果数据传送完毕,服务器也想断开连接,那么就发送一个FIN报文,并重新指定一个序号seq=w,确认号还是ack=u+1,表明可以断开连接。

4.第四次挥手:客户端收到报文后,一样发出一个ACK报文段做出应答,上一次客户端发送的报文段序号为u,那么这次序号就是seq=u+1,确认号为ack=w+1。此时客户端处于TIME_WAIT状态,需要经过一段时间确保服务器收到自己的应答报文后,才会进入CLOSED状态。

服务器收到ACK报文后,就关闭连接,也处于CLOSED状态了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C1Vxa8bt-1635066684897)(C:\Users\15921\AppData\Roaming\Typora\typora-user-images\image-20211024164019559.png)]

2.1为什么挥手需要四次?

这个问题可以换一种问法,也就是:中间两个步骤为什么不能合并呢?只要服务器收到客户端的FIN报文后,同时发送ACK报文和FIN报文不就可以三次挥手断开连接吗?

答案是通常情况下不行,因为ACK和FIN的触发时机是不一样的。我们要搞清楚一件事:服务器在收到FIN报文后可以立即发送ACK报文,表明我服务器收到了你的报文;但是服务器想发送FIN报文就需要等到处理完接收缓冲区的数据后才可以。所以挥手需要四次。

2.2为什么要等待2MSL?(为什么会存在一个TIME_WAIT状态?)

报文段最大生存时间MSL(Maximum SegmentLifetime),它是任何报文段被丢弃前在网络内的最长时间,超过这个时间报文将被丢弃。等待2MSL是为了确保服务器收到了最后一段ACK报文。

如何确保服务器收到了最后一段ACK报文?

如果服务器没有收到最后一段ACK报文,就会触发超时重传:服务器会再次发送FIN ACK报文。那么在2MSL的时间内,客户端会再次收到FIN报文,客户端就知道刚刚发送的ACK丢失,需要再次发送。

如果服务器收到了最后一段ACK报文,客户端在2MSL的时间内就不会收到任何报文,客户端就知道刚刚发送的ACK报文没有丢失,不需要再次发送,可以安心进入CLOSED状态了。


http://chatgpt.dhexx.cn/article/PX5sXwjm.shtml

相关文章

面试官,不要再问我三次握手和四次挥手

温馨提示:本篇文章会长期维护及更新,详情见:https://yuanrengu.com/2020/77eef79f.html 面试相关文章推荐: 面试必备 | 小伙伴栽在了JVM的内存分配策略。。。垃圾收集器(CMS、G1)及内存分配策略Java虚拟机…

C语言数据结构创建矩阵,及代入数据

创建一个这样的矩阵 数据由我们插入(定位坐标行列及插入的数据) 代码如下: 思路:将每个坐标节点和我们插入的节点坐标做对比,如果行列坐标都相等,则value置1并输出其相应的数据,否则value还是为0&#x…

数据结构-树(c语言实现篇)

数据结构之二叉树(c语言实现篇) 介绍树的概念和二叉树的概念和应用,内容主要是以二叉树为主。 1. 树 1.1 树的概念 树是n个结点的有限集,当n0时,称为空树。树是一种非线性的数据结构,与前面的线性表、栈和…

c语言的数据结构表达式求值

最近学习c语言的数据结构中有关栈的实现。下面是用栈实现表达式求值的一个实例,用的是顺序栈的形式 原理: List item 我们默认一‘#’开始,最后输入’#‘结束 在运算中的每一步中,任意两个相继出现的算符theta1和theta2之间的关…

C语言数据结构篇——栈的顺序存储

作者名:Demo不是emo 主页面链接:主页传送门创作初心:对于计算机的学习者来说,初期的学习无疑是最迷茫和难以坚持的,中后期主要是经验和能力的提高,我也刚接触计算机1年,也在不断的探索&#xf…

C语言数据结构之查找(顺序查找,折半查找)

C语言数据结构之查找(顺序查找,折半查找) tips:前些天已经学习了树和图的相关知识,今天来总结下两种常用的查找方式(顺序查找,折半查找)。 为了演示方便,顺序查找和折半…

【C语言数据结构7】--串的实现

串 一、什么是串 串就是我们常说的字符串,它同样是一个线性表。可能有人认为串就是元素为字符的线性表,但这种说法是不准确的。对于普通的线性表,它们关注的往往是单个元素,每个单独的元素都有独立的含义。比如我们用线性表存储…

C语言数据结构——查找(检索)

一、查找的基本概念 查找:查询某个关键字是否在(数据元素集合)表中的过程。也称作检索。 查找表: 由同一类型的数据元素(或记录)构成的集合。 主关键字: 能够惟一区分各个不同数据元素的关键字 次关键字: 通常不能惟一区分各个不同数据元素的…

C语言数据结构——广义表

C语言数据结构中,广义表和数组一样,也是线性表的一种推广! 广义表的定义: 广义表 LS 为n(n≥0)个元素的有穷序列,记作: LS (d1, d2, … dn) 其中&#xff1…

C语言数据结构——图

一、图的基本概念 图是由顶点集合及顶点间的关系集合组成的一种数据结构。vertex, edge 图G的定义是: G (V,E) 其中, V {x|x∈某个数据元素集合} E { (x,y)|x,y∈V} (无向图&#…

数据结构(c语言版本)

1.基本概念 1.1数据 对客观事物的符号表示,在计算机与科学中是指所有能输入到计算机并被计算机程序处理的符号的总称。 1.2数据元素 是数据的基本单位,在计算机程序中作为一个整体进行考虑和处理 1.3数据对象 是相同性质数据元素的集合&#xff0c…

c语言数据结构

目录 一、数据结构构造概述 1.1、什么是数据结构 1.2、数据的逻辑结构的4种分类 二、线性表 2.1、线性表概述 2.2、顺序表 2.3、链表 2.3.1、链表节点的创建 2.3.2、链表结点遍历 2.3.3、链表结点删除 2.3.4、链表的插入 ​ 三、栈和队列 3.1、栈概述 3.2、栈…

C语言数据结构知识点小结(全)

Catologue C语言数据结构一、基本概念和术语二、时间、空间复杂度(1)时间复杂度(2)空间复杂度 三、类C语言有关操作补充1:数组定义补充2:动态内存分配补充3:C中的参数传递 四、线性表&#xff0…

七丶青龙nvjdc部署教程+短信验证登录对接傻妞

青龙nvjdc部署教程短信验证登录对接傻妞Nolanjdc 没有服务器的先自行购买,这里推荐腾讯云2H4G8M首年70–点击购买 青龙面板安装教程 傻妞机器人安装教程 XDD安装教程 QQ交流:1014549449 --------------点击跳转 注丶只能对接一个,要么对接…

手机短信验证

在项目中经常会用到手机短信验证注册,登录等功能,所以我想写一篇文章来给大家提供一个参考。 阿里大于-个人感觉比较好用的短信验证平台,下面是接入阿里大于sdk的步骤。 阿里大于官网:直通车, 进入官网需要注册,注册…

014_关于session实现短信验证登录的前端启动

014_关于session实现短信验证登录的前端启动 1、进入到nginx相对应的文件夹,shfit右键,进入PowerShell并且执行nginx 2、启动我们的nginx,嘿嘿,可以访问我们的前端网页啦!!!它就是模仿我们的大众点评来着…

基于Redis的短信验证登录

基于Redis的短信验证登录 1、用户调用发送短信验证码接口2、用户调用登录/注册接口3、用户调用校验接口4、SpringMvc拦截器注册5、token刷新拦截器6、登录拦截器 1、用户调用发送短信验证码接口 用户调用sendCode()接口,把phone传到后端,后端对phone进行…

使用聚合数据短信API测试(短信验证登录)

搞一手聚合数据短信API测试(之前用阿里云的搞过,今天我们用聚合) 注册聚合账号!聚合官网链接登陆后进入短信服务API(免费提供十次) 添加自定义模板(审核速度看脸) 审核成功后得…

android studio 实现短信验证 登录

登录 http://www.mob.com/ 注册 创建项目 加入依赖 贴代码 classpath “com.mob.sdk:MobSDK:2018.0319.1724” apply plugin: ‘com.mob.sdk’ // 在MobSDK的扩展中注册SMSSDK的相关信息 这里使用自己的 appKey appSecret MobSDK {appKey “2e2974aec0” appSecret “1d35b87…

Java简单实现短信验证登录(Session、Redis)

前端设计 <div class"login-form"><div style"display: flex; justify-content: space-between"><el-input style"width: 60%" placeholder"请输入手机号" v-model"form.phone" ></el-input><e…