网络学习(三)TCP三次握手、四次挥手,及Wireshark抓包验证

目录

    • 一、什么是 TCP 三次握手?
    • 二、什么是 TCP 四次挥手?
    • 三、Wireshark抓包验证
      • 3.1 如何捕获三次握手、四次挥手
      • 3.2 TCP 三次握手的记录
      • 3.3 数据传输
      • 3.4 TCP 四次挥手的记录

在这里插入图片描述

一、什么是 TCP 三次握手?

TCP(Transmission Control Protocol,传输控制协议)的 三次握手(Three-Way Handshake)是 TCP 连接建立的过程。在 TCP 中,连接的建立和关闭都是通过客户端和服务器之间的一系列握手完成的。三次握手用于确保客户端和服务器之间的连接是双向的,并且双方都能发送和接受数据。

三次握手的过程如下:

在这里插入图片描述

注意:图中,seq表示序列号;seq=x中x表示在客户端序列号已经迭代到x了,如果是第一次请求,x就是0;seq=y中y表示在服务端序列号已经迭代到y了,如果是第一次响应,y就是0。

  1. 第一次握手(同步请求):
    • 客户端发送一个带有 SYN(同步序列编号)标志的 TCP报文段给服务器,请求建立连接。这个报文段还包含一个初始序列号,用于后续的数据传输。
    • 客户端进入 SYN_SENT 状态,等待服务器确认。
  2. 第二次握手(同步确认):
    • 服务器收到客户端的 SYN 报文段后,如果同意建立连接,会回复一个 SYN+ACK(同步确认)报文段。这个报文段同样包含一个确认序列号,确认客户端的序列号,并提供自己的初始序列号。
    • 服务器进入 SYN_RECEIVED 状态。
  3. 第三次握手(确认):
    • 客户端收到服务器的 SYN+ACK 报文段后,会发送一个带有 ACK(确认)表示的报文段给服务器,确认服务器的序列号。
    • 客户端和服务器都进入 ESTABLISHED 状态,此时连接完全建立,双方可以开始数据传输。

三次握手是 TCP 连接建立的必要步骤,它保证了在不可靠的网络环境中,TCP 能提供可靠的数据传输服务。

三次握手确保了以下几点:

  • 客户端和服务器都能发送和接收数据。
  • 双方都确认了对方的序列号,用于数据包的顺序恢复和重复检测。
  • 连接是双向的,确保了数据的可靠传输。

二、什么是 TCP 四次挥手?

TCP 四次挥手(Four-Way Wave)是TCP协议中终止一个已建立连接的过程。与三次握手用于建立连接类似,四次挥手用于在双方完成数据交换后,安全地关闭连接。四次挥手的过程 确保了所有数据都被正确传输,并且双方都同意关闭连接

TCP四次挥手的过程如下:

在这里插入图片描述

  1. 第一次挥手(终止请求):
    • 任意一方(通常是客户端)发送一个带有 FIN(Finish)标识的 TCP 报文段,表示数据传输完毕,希望关闭连接。这个报文段也包含一个序列号。
    • 发送 FIN 的一方进入 FIN_WAIT_1 状态。
  2. 第二次挥手(终止确认):
    • 接受 FIN 的一方(通常是服务器)会发送一个带有 ACK(Acknowledgement)表示的报文段,确认接收到 FIN。这个 ACK 报文段确认的是 FIN 报文段的序列号。
    • 发送 ACK 的一方进入 CLOSE_WAIT 状态,而发送 FIN 的一方收到 ACK 后进入 FIN_WAIT_2 状态。
  3. 第三次挥手(终止请求确认):
    • 当接收 FIN 的一方也完成了数据发送,它也会发送一个带有 FIN 标志的报文段,表名自己也完成了数据发送,希望关闭连接。
    • 发送 FIN 的一方进入 LAST_ACK 状态。
  4. 第四次挥手(最终确认):
    • 最初发送 FIN 的一方在收到第二个 FIN 后,会发送一个 ACK 报文段,确认接收到了对方的 FIN
    • 发送 ACK 的一方进入 TIME_WAIT 状态,等待足够的时间以确保 ACK 报文段到达对方。在此之后,连接正式关闭。

TIME_WAIT 状态的存在是为了确保最后一个 ACK 报文段能够到达对方,防止在网络延迟或阻塞的情况下丢失。在 TIME_WAIT 状态保持一段时间后(通常是最大段生存时间MSL的两倍),连接将被彻底关闭。

四次挥手的机制保证了在连接关闭过程中,所有的数据都被正确处理,并且双方都明确知悉连接的关闭,确保了TCP连接的 可靠性安全性

TCP协议中,大写的 ACK 和小写的 ack 有什么区别?

  1. 大写的 ACK
    • 大写的 ACK 是 TCP 协议头部的一个标志位(Flag),全称为 Acknowledgement,用于确认接收到了对方的数据。
    • ACK 标志位被设置为 1 时,表示这个数据包包含了确认信息,即接收方已经收到了某个序列号之前的所有数据。
    • ACK 标志位的 存在与否并不直接影响序列号,但他 决定了数据包是否包含确认信息
  2. 小写的 ack
    • 小写的 ack 是一个数值,全称为Acknowledgement Number,用于指出接收方期望接收的下一个节点的序列号
    • 每个TCP数据包中都有一个 ack 字段,ACK 标志位为1时,ack字段的值才是有效的,表示接收方成功接收并确认了 ack-1 及之前节点的字节。
    • ack 值是基于序列号的,序列号用于标识数据包中的数据字节,而 ack 值则用于确认这些字节已经被正确接收。

三、Wireshark抓包验证

3.1 如何捕获三次握手、四次挥手

显示过滤器中输入如下内容:

# 筛选目的地址为 192.168.1.164 的HTTP请求
http && ip.dst  == 192.168.1.164

在控制台执行如下命令:

curl http://192.168.1.164:6302/

查看 Wireshark 的捕获结果如下:

在这里插入图片描述

点击请求信息,可以看到当前 HTTP 请求的 Stream index 为 4,在显示过滤器中输入如下指令:

tcp.stream eq 4

Stream index:流索引,是用来标识一个 TCP 或 UDP 数据流的唯一编号。当你在分析网络流量时,尤其是在追踪一个特定的会话时,Stream index 是非常有用的。

  • Stream index 基于以下四个因素来确定:源IP地址目标IP地址源端口目的端口

或者右键需要查看的请求,跟踪流 -> TCP Stream,也可以快捷键 Ctrl + Alt + Shift + T

在这里插入图片描述

这里我们只是通过跟踪流来查看 HTTP 对应的 TCP 协议交互情况,所以先关闭弹出的信息。

在这里插入图片描述

这里就可以清晰看到 TCP 协议中 三次握手四次挥手 所对应的请求:

在这里插入图片描述

3.2 TCP 三次握手的记录

第一次握手:

  • 第一次连接是客户端主动要连接服务端的,可以看到传输控制协议里seq=0(seq是序列号),代表初次连接,ack=0(确认码,此时没有ACK标识位,所以ack不生效),初次连接为0。
  • 其次,还要给标志位,就是Flags。初次连接需要给SYN=1的标志位表示请求建立连接。

在这里插入图片描述

第二次握手:

  • 第二次握手是服务端的应答 6302 端口给 51707 的端口数据,初次连接所以 seq=0,ack=上一次客户端的序列号+1。
  • 标志位是SYN=1和ACK=1,代表这是一个确认的应答连接。

在这里插入图片描述

第三次握手:

  • 第三次握手是客户端61474给8089服务端的反馈,Seq=1,因为这是客户端的第二次交互了,Ack=上一次服务端连接的序列号+1。
  • 标志位为:ACK,表示确认收到了连接回复,三次握手就建立连接完毕。

在这里插入图片描述

3.3 数据传输

第4个包是建立HTTP请求,开始传输数据。

在这里插入图片描述

第5个包由服务端应答客户端,seq=1 为服务的第二次处理;ack=上一个TCP的请求长度+1。

在这里插入图片描述

第6个包中,seq=1,因为一直没有有效的数据;ack=82,仍为之前TCP数据包的长度。

在这里插入图片描述

第7个包中,服务端给客户端响应HTTP数据,seq=TCP传输的长度+1,ack=82,之后都是往复循环发送数据。

在这里插入图片描述

3.4 TCP 四次挥手的记录

数据传输完毕之后,开始4次挥手操作。在 TCP 协议中,通常描述的四次挥手过程是这样的:

  1. 第一次挥手: 客户端发送一个带有 FIN 标志的 TCP 数据包给服务器,请求终止连接。这时,客户端进入 FIN_WAIT_1 状态。
  2. 第二次挥手: 服务器接收到 FIN 后,会发送一个带有 ACK 标志的 TCP 数据包给客户端,确认收到了 FIN。此时,服务器进入 CLOSE_WAIT 状态,等待自己这边的数据发送完毕。
  3. 第三次挥手: 服务端在发送完自己所有的数据后,也会发送一个带有 FIN 标志的 TCP 数据包给客户端,请求终止连接。这是,服务器进入 LAST_ACK 状态。
  4. 第四次挥手: 客户端接收到服务器的 FIN 后,会发送一个带有 ACK 标志的TCP数据包给服务器,确认收到了 FIN。这时,客户端进入 TIME_WAIT 状态,等待足够长的时间(通常是2MSL)以确保服务器收到确认,之后连接才会真正关闭。

在这里插入图片描述

然而,在看到我们用 wireshark 抓取到的四次挥手时,却发现 实际跟本无法与理论挂钩

在这里插入图片描述

原因如下:

  • 在实际的 HTTP 请求中,情况可能与通常的四次挥手有所不同,这是因为 HTTP 请求通常在一个 TCP 连接上进行多次往返通信。在 HTTP/1.1 中,默认情况下连接是保持打开状态的(keep-alive。这意味着在一个完整的 HTTP 事务(请求-响应)之后,连接并不会立即关闭,而是可以继续用于后续的请求。
  • 在 Wireshark 中,你看到的第一次挥手可能包含了 ACK 标志位,是因为在发送 FIN 之前,客户端可能需要确认之前接收到的服务器数据。在某些情况下,客户端可能会在同一个数据包中同时发送 FINACK,这样可以减少网络往返次数,提高效率
  • 因此,即使你看到了 ACK 标志位被设置,这并不意味着四次挥手的模型不适用,而是可能反映了 HTTP 请求中 TCP 连接管理的优化行为。在HTTP的上下文中,FINACK 可以在同一挥手动作中合并,但这仍然符合 TCP 连接关闭的基本原则。

那么了解了为什么 FINACK 标志位会合并之后,为了加深理解,我们再来看下出现这种情况的场景。

合并 FINACK 标志位的场景:

  • 数据传输完成且无额外数据待发送: 当一方向另一方发送完所有数据,并且不再有数据需要发送时,它可以将 FIN 标志位设置为1,同时确认对方之前发送的数据,将 ACK 标志位也设置为1。
  • 零窗口通告: 如果接收方通告的接收窗口大小为0,发送方将无法发送数据,此时发送方可以发送带有 FINACK 标志位的 TCP 数据包来关闭连接,避免等待不必要的空闲时间。
  • 性能优化: 在一些实现中,操作系统可能选择合并 FINACK 以减少网络负载和延迟。

那么了解了合并 FINACK 标志位的场景有哪些后,为了加深理解,我们再来看下合并后的TCP挥手过程是怎样的:

合并后的挥手过程:(三次挥手)

FINACK 在同一个数据包中发送时,挥手过程可能会缩短至三次,这被称为 “三次挥手”。TCP 的 三次挥手 是指在断开连接时,双方各发送一个 FIN 标志位和一个 ACK 标志位来确认关闭连接。这里是如何发生的:

  1. 客户端发送 FIN+ACK 客户端决定关闭连接,发送一个带有 FINACK 标志位的TCP数据包。FIN 表示它已经没有数据要发送了,而 ACK 则是对服务器之前发送的数据的确认。
  2. 服务端回应 ACK 服务器接收到带有 FINACK 的包后,会发送一个仅带有 ACK 标志位的 TCP 数据包,确认接收到的客户端的 FIN,此时服务器进入 CLOSE_WAIT 状态。
  3. 服务器发送 FIN+ACK 当服务器也完成了数据发送并准备关闭连接时,它会发送一个带有 FINACK 标志位的TCP数据包。这里的 FIN 表名服务器也没有数据要发送了,ACK 是对客户端之前可能发送的任何数据的确认。
  4. 客户端回应 ACK 客户端接收到带有 FINACK 的包后,会发送一个带有 ACK 标志位的TCP数据包,确认接收到服务器的 FIN,此时客户端进入 TIME_WAIT 状态。

在这里插入图片描述

为什么客户端最后还要等待2MSL?

MSL(Maximum Segment Lifetime),TCP 允许不同的实现可以设置不同的 MSL 值。

  • 保证客户端发送的最后一个 ACK 报文能够到达服务器,因为这个 ACK 报文可能丢失,站在服务器的角度看来,我已经发送了 FIN+ACK 保卫呢请求断开了,客户端还没有给我回应,应该是我发送的请求断开报文它没有收到,于是服务器又会重新发送一次,而客户端就能在这个 2MSL 时间段内收到这个重传的报文,接着给出回应报文,并且会重启 2MSL 计时器。
  • 防止类似于 “三次握手” 中提到了的 已经失效的连接请求报文段 出现在本连接中。客户端发送完最后一个确认报文后,在这个 2MSL 事件中,就可以使本连接持续的时间内所产生的所有报文段都从移动中消失。这样新的连接中不会出现就链接的请求报文。

整理完毕,完结撒花~🌻





参考地址:

1.用wireshark抓包来分析TCP三次握手和四次挥手操作,https://blog.csdn.net/dfBeautifulLive/article/details/121889271

2.TCP四次挥手中间两次会合并成一次吗?https://www.zhihu.com/question/477295175/answer/2042547399

3.TCP三次握手和四次挥手,https://www.bilibili.com/video/BV18h41187Ep/

4.详解 TCP 连接的“三次握手”与“四次挥手”,https://blog.csdn.net/spade_Kwo/article/details/119464901

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机组成原理之存储器(二)

文章目录 随机读写存储器RAM静态MOS存储单元与存储芯片动态MOS存储单元与存储芯片 半导体存储器逻辑设计存储器的读写以及刷新存储器的读写动态存储芯片的刷新 随机读写存储器RAM 静态MOS存储单元与存储芯片 静态RAM用半导体管的导通和截止来记忆,只要不掉电&#x…

2.线性神经网络

目录 1.线性回归一个简化模型线性模型:可以看做是单层神经网络衡量预估质量训练数据参数学习显示解总结 2.基础优化方法小批量随机梯度下降总结 3.Softmax回归:其实是一个分类问题回归VS分类从回归到多类分类---均方损失Softmax和交叉熵损失 4.损失函数L…

使用插件永久解决IDEA使用Shift+F10失效问题(不需要换老版本输入法)

在日常编程中,使用快捷键可以大大提高开发效率。然而,有时候我们会遇到IDEA 中,ShiftF10 快捷键失效。这个蛋疼的问题现在终于可以得到解决,上个月在逛V2EX的时候看见一位大佬做的插件。 大佬链接:https://www.v2ex.c…

编程精粹—— Microsoft 编写优质无错 C 程序秘诀 02:设计并使用断言

这是一本老书,作者 Steve Maguire 在微软工作期间写了这本书,英文版于 1993 年发布。2013 年推出了 20 周年纪念第二版。我们看到的标题是中译版名字,英文版的名字是《Writing Clean Code ─── Microsoft’s Techniques for Developing》&a…

51单片机宏定义的例子

代码 demo.c #include "hardware.h"void delay() {volatile unsigned int n;for(n 0; n < 50000; n); }int main(void) {IO_init();while(1){PINSET(LED);delay();PINCLR(LED);delay();}return 0; }cfg.h #ifndef _CFG_H_ #define _CFG_H_// #define F_CPU …

nacos注册中心配置中心集群搭建

文章目录 学习连接1.Nacos安装与简单使用1.1. Nacos安装指南Windows安装下载安装包解压端口配置启动访问 Linux安装安装JDK上传安装包解压端口配置启动 1.2.服务注册到nacos使用步骤引入依赖配置nacos地址重启 示例父工程pom.xmluser-servicepom.xmlapplication.ymlUserApplica…

Jupyter Notebook 中 %run 魔法命令

目录 基本用法运行 Python 脚本运行 Jupyter Notebook 的其他单元格传递命令行参数 示例运行 Python 脚本示例运行其他 Jupyter Notebook 示例传递命令行参数示例 注意事项与 import 命令的区别%runimport 结论 %run 是 Jupyter Notebook 中的一个强大工具&#xff0c;它允许你…

【机器学习】第4章 决策树算法(重点)

一、概念 1.原理看图&#xff0c;非常简单&#xff1a; &#xff08;1&#xff09;蓝的是节点&#xff0c;白的是分支&#xff08;条件&#xff0c;或者说是特征&#xff0c;属性&#xff0c;也可以直接写线上&#xff0c;看题目有没有要求&#xff09;&#xff0c; &#xff0…

MySQL----InooDB行级锁、间隙锁

行级锁 行锁&#xff0c;也称为记录锁&#xff0c;顾名思义就是在记录上加的锁。 注意&#xff1a; InnoDB行锁是通过给索引上的索引项加锁来实现的&#xff0c;而不是给表的行记录加锁实现的&#xff0c;这就意味着只有通过索引条件检索数据&#xff0c;InnoDB才使用行级锁…

【开发工具】git服务器端安装部署+客户端配置

自己安装一个轻量级的git服务端&#xff0c;仅仅作为代码维护&#xff0c;尤其适合个人代码管理。毕竟代码的版本管理是很有必要的。 这里把git服务端部署在centos系统里&#xff0c;部署完成后可以通过命令行推拉代码&#xff0c;进行版本和用户管理。 一、服务端安装配置 …

【Kubernetes】k8s--安全机制

机制说明 Kubernetes 作为一个分布式集群的管理工具&#xff0c;保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介&#xff0c; 也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。 比如 kubectl 如果想向 …

新版FMEA培训内容中关于团队协作的部分可以怎么展开?

团队协作&#xff0c;作为新版FMEA的核心要素之一&#xff0c;其重要性不言而喻。在FMEA的分析过程中&#xff0c;团队成员的密切合作与沟通是确保分析全面性和准确性的关键。通过团队协作&#xff0c;不同领域的专家能够共同参与到潜在故障模式的识别、评估与预防中来&#xf…

解决ubuntu22.04共享文件夹问题

刚开机发现ubuntu里面的共享文件夹访问不了了 ubuntuwxy:/mnt/hgfs$ ls找了几篇博客&#xff0c;设置如下指令即可&#xff0c;记得退出当前目录重新进入刷新一下 sudo vmhgfs-fuse .host:/ /mnt/hgfs/ -o allow_other -o uid1000 仅供参考

针对indexedDB的简易封装

连接数据库 我们首先创建一个DBManager类&#xff0c;通过这个类new出来的对象管理一个数据库 具体关于indexedDB的相关内容可以看我的这篇博客 indexedDB class DBManager{}我们首先需要打开数据库&#xff0c;打开数据库需要数据库名和该数据库的版本 constructor(dbName,…

[WTL/Win32]_[中级]_[MVP架构在实际项目中应用的地方]

场景 在开发Windows和macOS的界面软件时&#xff0c;Windows用的是WTL/Win32技术&#xff0c;而macOS用的是Cocoa技术。而两种技术的本地语言一个主打是C,另一个却是Object-c。界面软件的源码随着项目功能增多而增多&#xff0c;这就会给同步Windows和macOS的功能造成很大负担…

Aigtek高压放大器在柔性爬行机器人驱动性能研究中的应用

实验名称&#xff1a;柔性爬行机器人的材料测试 研究方向&#xff1a;介电弹性体的最小能量结构是一种利用DE材料的电致变形与柔性框架形变相结合设计的新型柔性驱动器&#xff0c;所谓最小能量是指驱动器在平衡状态时整个系统的能量最小&#xff0c;当系统在外界的电压刺激下就…

开发一个python工具,pdf转图片,并且截成单个图片,然后修整没用的白边

今天推荐一键款本人开发的pdf转单张图片并截取没有用的白边工具 一、开发背景&#xff1a; 业务需要将一个pdf文件展示在前端显示&#xff0c;但是基于各种原因&#xff0c;放弃了h5使用插件展示 原因有多个&#xff0c;文件资源太大加载太慢、pdf展示兼容性问题、pdf展示效果…

应急便携式气象观测站

TH-BQX5自然灾害&#xff0c;如台风、暴雨、洪涝、干旱等&#xff0c;给人们的生命财产安全带来了巨大威胁。在应对这些灾害时&#xff0c;准确的气象观测数据是制定有效应对策略的基础。近年来&#xff0c;应急便携式气象观测站在自然灾害的监测和预警中发挥了越来越重要的作用…

在 Blazor 中在子组件和父组件之间共享数据

介绍 可以在Blazor 中创建一个子组件并在另一个组件中重用它。我们将非常轻松地在这些组件之间共享数据。我们将创建一个自定义文本框作为子组件。此自定义文本框将显示文本框中的当前字符数&#xff0c;并在需要时限制字符总数。我将逐步解释所有操作。 在 Visual Studio 中…

购物App需要进行软件测试吗?包括哪些测试内容?

随着移动互联网的飞速发展&#xff0c;购物App在人们的日常生活中扮演着越来越重要的角色。然而&#xff0c;由于App开发的复杂性和用户对于购物体验的高要求&#xff0c;保证App的质量成为了一项重要的任务。而软件测试作为确保App质量的关键环节&#xff0c;也日益受到重视。…