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

在这里插入图片描述

一、什么是 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

  • 29
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不愿放下技术的小赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值