【网络】TCP三次握手和四次挥手(感性理解)

目录

三次握手

文字描述三次握手过程

为什么是三次握手?

什么是SYN洪水?

连接和半连接队列

一次、两次握手行不行,四/五/六次握手行不行?

三次握手一定会成功吗?

三次握手的过程中可不可以携带数据

TCP中的ISN能不能固定

四次挥手

四次挥手文字描述

四次挥手客户端和服务端的状态变换

挥手为什么需要四次

四次挥手释放连接时,为什么要等待2MSL

TIME_WAIT和CLOSE_WAIT

TIME_WAIT会引起bind失败的问题

​编辑 服务器上大量出现close_wait是的原因


三次握手

感性理解:

小红:我有东西要给你,我们建立连接吧。(第一次握手)

小蓝:OK,我准备好了。(第二次握手)

小红:谢谢你受理我的请求。(第三次握手)

知识准备:

1.tcp报文是有类型的。根据类型不同做不同的动作。上图握手过程中标注的如ACK,SEQ等都是报头中的字段,实际上发送时是将上图中的标志位或字段进行处理再发送完整的报文,不要只关注表面的ACK......这些字眼。

2.三次握手并不是一定会成功。

3.连接建立后是要被OS管理起来的(先描述,在组织),维护一个连接是有成本的。

4.ACK:确认号是否有效。SYN:请求建立连接; 我们把携带SYN标识的称为同步报文段。SEQ表示序号,ACK_SEQ表示确认序号。

文字描述三次握手过程

握手过程

文字描述部分以上图为例:

第一次握手,客户端向服务器发送连接请求,报头中SYN标志位设置为1,序号为X。此时客户端的状态是【SYN_SENT】

第二次握手,服务端收到客户端的SYN后,向客户端发送ACK+SYN,将报头中的ACK和SYN标志位设置为1,确认序号为X+1,序号设为Y。服务端的的状态是【SYN_RCVD】,客户端收到确认后先建立连接,状态变为【ESTABUSHED】

第三次握手,客户端向服务端发送确认,将报头中的ACK设置为1,确认序号为Y+1,序号为X+1。服务端收到确认后,状态变为【ESTABUSHED】

为什么是三次握手?

原因1:三次握手以最低成本验证了双方通信信道的通畅,保证通信双反既能发消息,也能收消息。验证过程如下:

第一次握手,服务端收到客户端发来的报文后,服务端知道【客户端的发送能力和服务端的接收能力是没问题的】。

第二次握手,客户端收到了服务端的ACK和SYN,客户端知道【客户端的发送和接收能力,服务端的接收和发送都是没问题的】。注意:服务端此时还不能确认客户端的接收能力,需要等收到应答后才能确定。

第三次握手,服务端收到了来自客户端的应答,此时服务端知道【客户端的接收和发送能力,服务端的发送和接收能力都是没问题的】。

原因2:在三次握手的过程中,是客户端先建立了连接,服务端才建立连接。这就有效预防了单机攻击服务器的情况,没有明显的漏洞。这就好比你的朋友叫你吃辣根,你和他说:“你先吃,你吃了我就吃”。此时,你的朋友如果想要恶搞你,就要先尝到辣根的刺激。

什么是SYN洪水?

SYN攻击就是客户端在短时间内,不断的向服务端发送SYN包,服务端收到SYN后回复确认包并等待客户端确认。这些SYN包长时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪。

连接和半连接队列

服务器第一次收到客户单发来的SYN后处于SYN_RCVD状态,此时双方还没有完全建立连接。服务器会把这种状态下的请求连接放在队列中,这个队列称为半连接队列。

三次握手完成后,会发完全建立的连接放到全连接队列中。

一次、两次握手行不行,四/五/六次握手行不行?

不行,原因如下:

1.一次/二次握手不行,不知道双方的通信信道是否通畅。有明显的漏洞,抵不住单机SYN洪水攻击。

2.四/五/六次握手按照理论上来讲是没问题的,既然三次握手就已经能验证双方的通信信道是否通畅了,多次握手也一定能验证。但是这无非是单纯的在浪费资源,花100块就能解决的问题,为什么要花200呢?而且对于偶数次的握手而言,是服务端先建立的连接,这是有明显漏洞的。

3.需要注意的是,即使是三次握手,客户端先建立连接。也不能完全的避免攻击问题,但是这本来就不是建立握手要解决的问题。

三次握手一定会成功吗?

不一定。

1.我们认为,只有收到了应答,才确认历史消息是被收到的,是可靠的。

2.总有最新的消息没有应答,,对于第三次握手来说,就是最新的消息,不能保证可靠性。

3.如果第三次握手丢失了,客户端和服务端的反应如下:

服务端

第三次握手丢失后,根据超时重传机制重新发送SYN+ACK,如果重发指定次数后,仍然没有收到客户端的应答,一段时间后,服务端自动关闭这个连接。

客户端

对于客户端而言,第三次握手的ACK发出后,客户端认为已经建立了连接,此时如果向服务端发送消息,服务端会返回一个RST设置为1的包,此时会重新向服务端建立连接。如果客户端收到了服务端发送的SYN+ACk,客户端会从新发送ACK.

三次握手的过程中可不可以携带数据

第一次、第二次握手不可以携带数据,如果有人要攻击服务器,在第一次握手中携带大量的数据,并疯狂的发送SYN报文,这会让服务器花费很多的时间,空间来接收报文。简单的说就是容易让服务器受到攻击。

第三次握手的时候可以携带数据,此时的客户端已经处于连接状态了,这时的客户端已经知晓了服务端的接收和发送能力是否正常,所以携带数据是OK的。

TCP中的ISN能不能固定

不能,原因如下:

1.TCP初始化序号设置为一个固定值,这样会容易被攻击者猜测到后续的序号,从而遭到攻击。

2.假设服务端和客户端由于某种原因不停的断开和重连,那么之前交互的报文很可能在连接断开后没有到达服务端,而是在新连接建立后到达服务端,如果ISN是固定的,就可能会出现两次连接希望收到的序列号是相同的。

四次挥手

 感性理解:

小蓝:我要删除你的联系方式,不在联系。

小红:好的

小红:我也要删除你的联系方式,此后不在联系。

小蓝:OK

知识准备:
1.对于接下来要描述的四次挥手,所谓的不再发送数据,指的是不发用户数据,在底层还是要对报文的交互进行管理。

2.FIN:通知对方, 本端要关闭了, 我们称携带FIN标识的为结束报文段。RST: 对方要求重新建立连接; 我们把携带RST标识的称为复位报文段。

四次挥手文字描述

1.第一次挥手,客户端向服务端发送FIN设置为1的报文,想要断开连接。

2.第二次挥手,服务端收到FIN后,向客户端发送ACk设置为1的确认,同意断开连接。

3.第三次挥手,服务端向客户端发送FIN设置为1的报文,请求断开连接。

4.第四次挥手,客户端向服务端发送ACk设置为1的确认报文,同意断开连接。

四次挥手客户端和服务端的状态变换

挥手为什么需要四次

1.客户端和服务端都要分别释放连接。

2.TCP是全双工的模式:

当小蓝和小红说:“我们别在联系”时,只表示小蓝已经没有什么话想和小红说了。这个时候小蓝还可以接收小红发来的数据。

当小红和小蓝说:“你可以不在联系我”的时候,小红知道小蓝已经没有话要和我说了,但是我还可以向她发送数据。

当小红对小蓝说:“我也要和你不在联系”时,说明小红也无话可说了,此后双方就和平的断开这次连接。

综上所述,四次挥手以最低成本断开了双方的连接。

四次挥手释放连接时,为什么要等待2MSL

介绍:MSL指的是一段TCP报文在传输过程中的最大生命周期。2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的时长。

和第三次挥手一样的道理,第四次挥手是不可靠的,可能丢失。为了确认服务端是否收到了客户端发出的确认报文,所以在客户端发送完ACK确认报文之后,会设置一个时长为2MSL的计时器。

1.服务端如果在1MSL内没有收到客户端发来的ACK确认包,就会再次向客户端发送FIN报文。

2.如果在2MSL内,再次收到了来自服务端的FIN报文,说明服务端没有收到确认。当客户端再次发送确认后,计时器重置为2MSL。

3.如果客户端在2MSL的时间内没有再次收到来自服务端的FIN报文,说明服务端征程接收到了ACK确认报文,客户端进入到CLOSED状态,“四次挥手”完成。

4.综上所述,客户端要经历2MSL的TIME_WAIT状态,这也是为什么客户端比服务器晚进入CLOSED阶段的原因。

TIME_WAIT和CLOSE_WAIT

1.对于主动断开连接的一方来说,会进入到是TIME_WAIT状态。

2.对于被动断开连接的一方来说,两次挥手完成,进入到CLOSE_WAIT状态。

3.因为TCP协议是对等的,上述的描述和谁是C谁是S没有关系。

TIME_WAIT会引起bind失败的问题

1.服务器要处理大量的客户端连接。

2.如果是有服务端主动关闭连接,就会产生TIME_WAIT状态。

3.这个连接会占一个通信五元组,如果有新的客户端连接的IP和端口号与TIME_WAIT占用的连接失败,就会bind失败。

解决办法:

 服务器上大量出现close_wait是的原因

服务器没有正确的关闭socket,四次挥手没有正确完成,这是BUG,加上对应的close即可解决问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/14837.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flutter开发实战-自定义Switch开关控件Widget

flutter开发实战-自定义Switch开关控件 在flutter中实现自定义Switch,主要实现类似IOS的UISwitch样式的开关控件 一、效果图 二、实现Switch开关的Widget 实现自定义Switch的Widget,主要实现交织动画。 交织动画 有些时候我们可能会需要一些复杂的动画…

OpenCV在一个图像上画一个空心绿色的圆和一个实心红色的圆

/*** void cvCircle( CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int line_type=8, int shift=0 );* Opencv画点 其实画的是小圆圈* img:图像。* center:圆心坐标。* radius:圆形的半径。* color:线条的颜色。* thickness:如果是正数,表…

了解k8s容器组pods

一:Pods概述 在 部署第一个应用程序 中创建 Deployment 后,k8s创建了一个 Pod(容器组) 来放置应用程序实例(container 容器) Pod 容器组 是一个k8s中一个抽象的概念,用于存放一组 container&a…

文字和祝福语:创意的粒子效果网页(❤️好看好用❤️)HTML+CSS+JS

✨博主:命运之光 🌸专栏:Python星辰秘典 🐳专栏:web开发(简单好用又好看) ❤️专栏:Java经典程序设计 ☀️博主的其他文章:点击进入博主的主页 前言:欢迎踏入…

Stable Diffusion 多角度人设立绘快速生成多种方法

对于插画师构建人物立绘图设计一套多方位的人设可能要很久,但是使用SD进行操作的话就非常简单了,这个利用ControlNet骨骼图进行配置操作。 供一些样图参考,也可以使用ADetailer进行人物相关部位的修复。 文章目录 准备工作关键词绘制使用骨骼…

Git--远程操作

文章目录 前言一、理解分布式版本控制系统二、远程仓库1.新建远程仓库2.克隆远程仓库3.向远程仓库推送4.拉取远程仓库5.配置Git忽略特殊文件 给命令配置别名 总结 前言 正文开始!!! 一、理解分布式版本控制系统 我们目前所说的所有内容(工作区,暂存区,版本库等等),都是在本地…

数据库-SQL-DML语句

文章目录 DML语句添加数据修改数据DML-删除数据 DML语句 添加数据 表的结构 修改数据 DML-删除数据 DML-总结:

【Redis】2、Redis 的 Java 客户端(Jedis 和 SpringDataRedis)

目录 零、Redis 的 Java 客户端有哪些?二、Jedis 客户端(1) 引依赖(2) 连接 Redis 服务并测试(3) Redis 连接池 三、SpringDataRedis 介绍四、SpringBoot 中集成 SpringDataRedis(1) 引入依赖(2) 配置文件中书写相关配置(3) RedisTemplate 的默认序列化方式(4) 自定…

Qt保存代码

补全保存代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//字体按钮对应的槽函数 void Widget::on_fontBtn_clicked() {…

TCP 协议报文

TCP 提供面向连接的通信传输,面向连接是指在传送数据之前必须先建立连接,数据传送完成后要释放连接。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。在TCP/IP协议中,TCP协议提供可靠的连接服务,连接…

Adobe中修改注释签名

控制面板-> 系统和安全-> 管理工具-> 计算机管理-> 打开“计算机管理”对话框-> 在左边栏的系统工具下选择本地用户和组-> 点击“用户”->选择要改的用户名->右键重命名 打开Adobe Acrobat->点击"编辑"->首选项->注释 ->把 “登…

交叉导轨的结构与特长

在交叉导轨中,精密滚柱互相直交地组合在一起的滚柱保持架与设置在专用轨道上的90V形沟槽滚动面组合起来使用。通过将2列滚子导轨平行地装配,使导轨系统能承受4个方向的负荷。而且,因能向交叉滚子导轨施加预压,从而能获得无间隙且高…