TCP三次握手四次挥手

news2024/12/24 9:36:48

文章目录

      • TCP 三次握手和四次挥手
        • 1、三次握手过程
        • image-20230710094309497
        • 2、为什么要三次握手
        • 3、第 2 次握手传回了 ACK,为什么还要传回 SYN?
        • 4、断开连接-TCP 四次挥手
        • 5、为什么要四次挥手
        • 6、丢包问题
        • 7、为什么不能把服务器发送的 ACK 和 FIN 合并起来,变成三次挥手?
        • 8、如果第二次挥手时服务器的 ACK 没有送达客户端,会怎样?
        • 9、为什么第四次挥手客户端需要等待 2*MSL(报文段最长寿命)时间后才进入 CLOSED 状态?


TCP 三次握手和四次挥手

1、三次握手过程

image-20230710094309497

建立一个 TCP 连接需要“三次握手”,缺一不可 :

  • 一次握手:客户端发送带有 SYN(SEQ=x) 标志的数据包 -> 服务端,然后客户端进入 SYN_SEND 状态,等待服务器的确认;
  • 二次握手:服务端发送带有 SYN+ACK(SEQ=y,ACK=x+1) 标志的数据包 –> 客户端,然后服务端进入 SYN_RECV 状态
  • 三次握手:客户端发送带有 ACK(ACK=y+1) 标志的数据包 –> 服务端,然后客户端和服务器端都进入ESTABLISHED 状态,完成TCP三次握手。

当建立了 3 次握手之后,客户端和服务端就可以传输数据啦!

2、为什么要三次握手

三次握手的目的是建立可靠的通信信道,说到通讯,简单来说就是数据的发送与接收,而三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。

  1. 第一次握手 :Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
  2. 第二次握手 :Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
  3. 第三次握手 :Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常

三次握手就能确认双方收发功能都正常,缺一不可。

image-20230710092357017

如果已失效的报文重新发起请求,那么在两次握手的情况下,服务端认为是2个连接,客户端认为是1个连接,会造成状态不一致的情况,但如果是三次握手的话,服务端最后收不到ACK包,自然不会认为连接建立成功;三次握手本质上来说就是解决网络信道不可靠的问题。

3、第 2 次握手传回了 ACK,为什么还要传回 SYN?

服务端传回发送端所发送的 ACK 是为了告诉客户端:“我接收到的信息确实就是你所发送的信号了”,这表明从客户端到服务端的通信是正常的。回传 SYN 则是为了建立并确认从服务端到客户端的通信。

SYN 同步序列编号(Synchronize Sequence Numbers) 是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立正常的 TCP 网络连接时,客户机首先发出一个 SYN 消息,服务器使用 SYN-ACK 应答表示接收到了这个消息,最后客户机再以 ACK(Acknowledgement)消息响应。这样在客户机和服务器之间才能建立起可靠的 TCP 连接,数据才可以在客户机和服务器之间传递。

4、断开连接-TCP 四次挥手

image-20230710093810523

断开一个 TCP 连接则需要“四次挥手”,缺一不可 :

  1. 第一次挥手 :客户端发送一个 FIN(SEQ=X) 标志的数据包->服务端,用来关闭客户端到服务器的数据传送。然后,客户端进入 FIN-WAIT-1 状态。
  2. 第二次挥手 :服务器收到这个 FIN(SEQ=X) 标志的数据包,它发送一个 ACK (SEQ=X+1)标志的数据包->客户端 。然后,此时服务端进入CLOSE-WAIT状态,客户端进入FIN-WAIT-2状态。
  3. 第三次挥手 :服务端关闭与客户端的连接并发送一个 FIN (SEQ=y)标志的数据包->客户端请求关闭连接,然后,服务端进入LAST-ACK状态。
  4. 第四次挥手 :客户端发送 ACK (SEQ=y+1)标志的数据包->服务端并且进入TIME-WAIT状态,服务端在收到 ACK (SEQ=y+1)标志的数据包后进入 CLOSE 状态。此时,如果客户端等待 2MSL 后依然没有收到回复,就证明服务端已正常关闭,随后,客户端也可以关闭连接了。

只要四次挥手没有结束,客户端和服务端就可以继续传输数据!

5、为什么要四次挥手

TCP是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。

举个例子:A 和 B 打电话,通话即将结束后。

  1. 第一次挥手 : A 说“我没啥要说的了”
  2. 第二次挥手 :B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话
  3. 第三次挥手 :于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”
  4. 第四次挥手 :A 回答“知道了”,这样通话才算结束。

6、丢包问题

image-20230710093238355

7、为什么不能把服务器发送的 ACK 和 FIN 合并起来,变成三次挥手?

因为服务器收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复 ACK,表示接收到了断开连接的请求。等到数据发完之后再发 FIN,断开服务器到客户端的数据传送

8、如果第二次挥手时服务器的 ACK 没有送达客户端,会怎样?

客户端没有收到 ACK 确认,会重新发送 FIN 请求。

9、为什么第四次挥手客户端需要等待 2*MSL(报文段最长寿命)时间后才进入 CLOSED 状态?

第四次挥手时,客户端发送给服务器的 ACK 有可能丢失,如果服务端因为某些原因而没有收到 ACK 的话,服务端就会重发 FIN,如果客户端在 2*MSL 的时间内收到了 FIN,就会重新发送 ACK 并再次等待 2MSL,防止 Server 没有收到 ACK 而不断重发 FIN。

MSL(Maximum Segment Lifetime) : 一个片段在网络中最大的存活时间,2MSL 就是一个发送和一个回复所需的最大时间。如果直到 2MSL,Client 都没有再次收到 FIN,那么 Client 推断 ACK 已经被成功接收,则结束 TCP 连接。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

qt开发技巧之嵌入式linux qt按钮点击触发两次

1.问题 移植qt5.12.9到嵌入式linux系统,tslib作为触摸输入,开发平台是imx6ull,点击pushbutton按钮会出现触发两次点击的情况。 2.解决 vi /etc/profile,在 /etc/profile里添加环境变量,禁止QT自带输入检测&#xff0…

vue-watch监听器

1. 概述 watch是 vue 中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作。 Vue官网很明确的建议我们这样使用watch侦听属性:当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。 2. 用…

【通览一百个大模型】XLNet(Google)

XLNet 欢迎订阅阅读【大模型&NLP&算法】。 作者:王嘉宁本文章内容为转载或整理;仓库链接:https://github.com/wjn1996/LLMs-NLP-Algo 【通览一百个大模型】XLNet(Google) 作者:王嘉宁&#xff0…

lua脚本语言学习笔记

Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能。 因为我们使用redis的时候一般要写lua脚本,这篇文章就介绍一下lua脚本语言的基础用…

Python 算法基础篇:时间复杂度和空间复杂度简介

Python 算法基础篇:时间复杂度和空间复杂度简介 引言 1. 时间复杂度 a ) 常见的时间复杂度 b ) 时间复杂度示例 2. 空间复杂度 a ) 常见的空间复杂度 b ) 空间复杂度示例 结论 引言 在学习和分析算法时,时间复杂度和空间复杂度是两个关键概念。它们帮助…

【Python】类型注解 ④ ( 函数类型注解 | 函数形参类型注解语法 | 函数返回值类型注解 )

文章目录 一、函数形参类型注解1、函数中由于类型缺省导致的提示问题2、函数形参类型注解语法3、代码示例 - 函数形参类型注解 二、函数返回值类型注解1、函数返回值类型注解语法2、代码示例 - 函数返回值类型注解 一、函数形参类型注解 1、函数中由于类型缺省导致的提示问题 由…

LSTM对比Bi-LSTM的电力负荷时间序列预测(Matlab)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

小程序api的promise化

小程序根目录cmd运行安装命令 npm install --save miniprogram-api-promise1.0.4 安装完成之后先到根目录中删除miniprogram_npm文件夹(不删除构建npm时可能会出现问题) 删除之后再在工具中点击构建npm 构建成功之后会看到根目录中重新出现了miniprogram_npm文件夹 在app.j…

P1747 好奇怪的游戏

好奇怪的游戏 题目背景 《爱与愁的故事第三弹shopping》娱乐章。 调调口味来道水题。 题目描述 爱与愁大神坐在公交车上无聊,于是玩起了手机。一款奇怪的游戏进入了爱与愁大神的眼帘:***(游戏名被打上了马赛克)。这个游戏类似…

修复漏洞(三)升级Docker里面的镜像(MySQL、Nginx等)

前言 因原版本检测出来存在漏洞,故需升级底层镜像 步骤 先看看自己现在的是什么版本,教你们一个骚操作,查看Docker里面的Mysql或者其他容器版本都不用百度出来的这么麻烦首先docker images,查看镜像ID然后docker inspect 镜像I…

2、Java入门教程【IDEA】

1、下载 IDEA社区版:下载地址 IDEA管理JAVA程序的结构: project 项目、工程module 模块package 包class 类 2、创建工程 创建【project】 点击【create】后,项目结构如下: 创建【package】 我们继续在【src】目录下创建【pack…

Python中的break和continue语句应用举例

Python中的break和continue语句应用举例 在进行Python编程时候,有时需要,对循环中断或跳过某部分语句,此时常会用到break语句或continue语句。本文将通过实际例子阐述这两个语句的用法。 1.break语句 break语句是实现在某个地方中断循环&a…

js逆向补环境-b站志远二期最后8节课笔记

目录 一、基础知识1、什么是纯净V82、什么是BOM和DOM3、node环境/浏览器环境/V8引擎区别4、如何本地调试js补环境5、补环境相对于逆向算法的好处6、vm和vm2介绍 二、8个视频内容笔记概括1、补环境基本知识/头条案例手动插桩补2、Proxy代理/toString函数保护介绍3、补环境框架设…

安卓UI:Switch和ToggleButton

目录 一、Switch和ToggleButton介绍 Switch常用属性: ToggleButton属性: 二、Switch和ToggleButton常用方法 Switch常用方法: ToggleButton常用方法: 三、Switch和ToggleButton的使用 MainActivity: activity_main&#xff1…

【代码随想录 | Leetcode | 第四天】数组 | 螺旋矩阵 | 59

前言 欢迎来到小K的Leetcode|代码随想录|专题化专栏,今天将为大家带来螺旋矩阵的分享✨ 目录 前言59. 螺旋矩阵 II总结 59. 螺旋矩阵 II 给你一个正整数 n ,生成一个包含 1 到 n2 所有元素,且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 …

【C语言进阶(八)】动态内存管理

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:C语言学习分享⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学习更多C语言知识   🔝🔝 动态内存规划 1. 前言2. 为什么要学…

ElasticSearch索引(index)当中的增删改查操作

文章目录 一、创建索引(Create Index):二、更新索引的设置(Update Index Settings):三、获取当前索引的设置(Get Index Settings):四、删除索引(Delete Index…

Python(十三)数据类型——整数类型

❤️ 专栏简介:本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中,我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 :本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

N!9个OA高危漏洞利用工具v1.1.6

工具介绍 该工具使用了ExpDemo-JavaFX项目,保留了核心的数据包请求接口,使用jdk1.8环境开发。目前只编写了oa系列,对相关漏洞进行复现和分析,极力避免exp的误报和有效性。 关注【Hack分享吧】工众号,回复关键字【2305…

基于linux下的高并发服务器开发(第一章)- fcntl函数

13 / fcntl函数 #include <unistd.h> #include <fcntl.h> int fcntl(int fd, int cmd, ...); 参数&#xff1a; fd : 表示需要操作的文件描述符 cmd: 表示对文件描述符进行如何操作 - F_DUPFD : 复制文件描述符,复制的是第一个参数fd&#xff0c; …