解密TCP连接断开:四次挥手的奥秘和数据传输的安全

本文涉及的产品
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 1个月
简介: 本文将介绍TCP连接的断开过程,重点关注四次挥手的过程和状态变迁,以及为什么挥手需要四次和为什么需要TIME_WAIT状态。在TCP连接断开的过程中,双方需要发送FIN和ACK报文来确保数据的可靠传输和连接的正确关闭。挥手需要四次的原因是为了确保数据的完整传输和连接的可靠关闭。

TCP 连接断开

在当今数字化时代,互联网已经成为了人们生活中不可或缺的一部分。而在互联网的基础之上,TCP协议扮演着关键的角色,它负责着数据在网络中的可靠传输。在TCP连接的建立过程中,我们已经了解了三次握手的过程和原理。然而,连接的建立只是TCP协议的一部分,同样重要的是连接的断开过程。本文将重点探讨TCP连接的断开过程,包括四次挥手的过程和状态变迁,以及为什么挥手需要四次和为什么需要TIME_WAIT状态。通过深入理解TCP连接断开的过程,我们可以更好地理解网络通信的原理

TCP 四次挥手过程和状态变迁

TCP断开连接需要通过四次挥手的方式。双方都有能力主动断开连接,一旦断开连接,主机中的各种「资源」将被释放。那么我们将详细讲解下TCP四次挥手的原理及过程!

image

  • 当客户端打算关闭连接时,它会发送一个TCP首部中FIN标志位被置为1的报文,即FIN报文。随后,客户端进入FIN_WAIT_1状态。
  • 当服务端收到该报文后,会向客户端发送一个ACK应答报文,并进入CLOSED_WAIT状态。
  • 客户端接收到服务端的ACK应答报文后,进入FIN_WAIT_2状态。
  • 服务端等待处理完数据后,也会向客户端发送一个FIN报文,然后进入LAST_ACK状态。
  • 客户端收到服务端的FIN报文后,会回复一个ACK应答报文,并进入TIME_WAIT状态。
  • 一旦服务端收到了ACK应答报文,就进入CLOSE状态,这样服务端就完成了连接的关闭。
  • 客户端经过2MSL一段时间后,自动进入CLOSE状态,这样客户端也完成了连接的关闭。

在TCP连接的断开过程中,我们可以观察到每个方向都需要发送一个FIN报文和接收一个ACK报文,因此通常将这个过程称为四次挥手。

需要注意的一点是,只有主动发起关闭连接的一方,才会进入TIME_WAIT状态。这是因为在关闭连接后,客户端需要等待一段时间(通常为两倍的最大报文段生存时间,也即2MSL)来确保服务端收到了自己的ACK应答报文。这样做的目的是为了防止已经关闭的连接上出现延迟的报文段,确保连接的可靠关闭。而服务端则不需要等待这段时间,因此没有TIME_WAIT状态。

为什么挥手需要四次?

为了更好地理解为什么挥手需要四次,让我们再来回顾一下双方发出FIN包的过程。这样我们就能理解为什么需要四次挥手了。

在关闭连接时,当客户端向服务端发送FIN时,这仅仅表示客户端不再发送数据了,但是它仍然可以接收数据。

当服务端收到客户端的FIN报文时,它首先会回复一个ACK应答报文。然而,服务端可能还有数据需要处理和发送,所以它会等待直到它不再发送数据时,才会发送FIN报文给客户端,表示同意现在关闭连接。

通过上述过程,我们可以看出,服务端通常需要等待完成数据的发送和处理,所以服务端的ACK和FIN通常会分开发送,这就导致了比三次握手多了一次挥手的过程。

为什么 TIME_WAIT 等待的时间是 2MSL?

MSL是Maximum Segment Lifetime,即报文的最大生存时间,它表示报文在网络中存在的最长时间。超过此时间,报文将被丢弃。因为TCP协议是基于IP协议的,IP头部有一个TTL字段,它表示数据报可以经过的最大路由数。每经过一个路由器,TTL值就减1。当TTL值为0时,数据报将被丢弃,并且发送ICMP报文通知源主机。

MSL和TTL的区别在于单位。MSL的单位是时间,而TTL是经过的路由跳数。因此,为了确保报文已经自然消亡,MSL应该大于或等于TTL消耗为0的时间。

TIME_WAIT等待2倍MSL的合理解释是:网络中可能存在来自发送方的数据包。当这些数据包被接收方处理后,它会向对方发送响应,因此往返需要等待2倍的时间。就是确保最后一个ACK被服务端接收到了,如果没有接收到也要给足时间让服务器端的第三次挥手的FIN重新传过来。

举个例子,如果被动关闭方没有收到断开连接的最后一个ACK报文,就会触发超时重发FIN报文。另一方收到FIN报文后,会重发ACK给被动关闭方,这样来回就需要2个MSL的时间。

2MSL时间是从客户端接收到FIN后发送ACK开始计时的。如果在TIME_WAIT时间内,因为客户端的ACK没有传输到服务端,客户端又接收到了服务端重发的FIN报文,那么2MSL时间将重新计时。

在Linux系统中,默认的2MSL时间是60秒,即一个MSL为30秒。Linux系统停留在TIME_WAIT状态的时间是固定的60秒。
在Linux内核代码中,它的定义名为TCP_TIMEWAIT_LEN:

#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT 
                                    state, about 60 seconds  */

如果要修改TIME_WAIT的时间长度,只能修改Linux内核代码中TCP_TIMEWAIT_LEN的值,并重新编译Linux内核。

为什么需要 TIME_WAIT 状态?

TIME_WAIT 状态的存在是为了确保网络连接的可靠关闭。只有主动发起关闭连接的一方(即主动关闭方)才会有 TIME_WAIT 状态。

TIME_WAIT 状态的需求主要有两个原因:

  • 防止具有相同「四元组」的「旧」数据包被收到:在网络通信中,每个 TCP 连接都由源 IP 地址、源端口号、目标 IP 地址和目标端口号这四个元素唯一标识,称为「四元组」。当一方主动关闭连接后,进入 TIME_WAIT 状态,它仍然可以接收到一段时间内来自对方的延迟数据包。这是因为网络中可能存在被延迟传输的数据包,如果没有 TIME_WAIT 状态的存在,这些延迟数据包可能会被错误地传递给新的连接,导致数据混乱。通过保持 TIME_WAIT 状态,可以防止旧的数据包干扰新的连接。
  • 保证「被动关闭连接」的一方能被正确关闭:当连接的被动关闭方接收到主动关闭方的 FIN 报文(表示关闭连接),它需要发送一个确认 ACK 报文给主动关闭方,以完成连接的关闭。然而,网络是不可靠的,ACK 报文可能会在传输过程中丢失。如果主动关闭方在收到 ACK 报文之前就关闭连接,被动关闭方将无法正常完成连接的关闭。TIME_WAIT 状态的存在确保了被动关闭方能够接收到最后的 ACK 报文,从而帮助其正常关闭连接。

防止旧连接的数据包

假设TIME-WAIT状态没有适当的等待时间或时间过短,延迟的数据包抵达后可能会引发严重的问题。

image

例如,服务端在关闭连接之前发送的SEQ = 301报文被网络延迟了。然后,同一端口的TCP连接被复用,并且延迟的SEQ = 301到达了客户端。在这种情况下,客户端有可能正常地接收到这个过期的报文,从而导致数据错乱等严重问题的发生。

为了解决这个问题,TCP设计了一个机制,即经过2MSL的时间,足够让连接中的两个方向上的数据包都被丢弃。这样,原来连接的数据包在网络中自然消失,再出现的数据包一定是由新建立的连接产生的,从而避免了数据错乱等问题的发生。

保证连接正确关闭

TIME-WAIT状态的作用是等待足够的时间,以确保最后的ACK报文能够被被动关闭方接收,并帮助其正常关闭。

假设TIME-WAIT没有适当的等待时间或时间过短,断开连接可能会导致以下问题:

image

例如,如果在四次挥手的过程中,客户端发送的最后一个ACK报文在网络中丢失,并且客户端的TIME-WAIT状态过短或没有设置,则客户端会直接进入CLOSE状态,而服务端则会一直处于LAST-ACK状态。这种情况下,连接无法正常关闭。

另外,当客户端发起建立连接的SYN请求后,如果服务端发送的RST报文给客户端,连接建立的过程将会被终止。

如果TIME-WAIT等待的时间足够长,会发生以下两种情况:

  • 服务端正常接收到四次挥手的最后一个ACK报文,从而正常关闭连接。
  • 服务端没有收到四次挥手的最后一个ACK报文时,会重发FIN关闭连接报文并等待新的ACK报文。

因此,客户端在TIME-WAIT状态等待2MSL时间后,可以确保双方的连接都能够正常关闭。

这里再科普一下有关知识,大多数三次握手和四次挥手都没有提到。为什么第三次挥手的时候会发送ack呢?不是正常就是发送fin就可以了吗?

在TCP协议中,除了初始连接的第一个SYN包,其中ACK字段被设置为0,而其他所有的TCP包都会将ACK字段设置为1。这个ACK字段的作用是用来确认接收方已经成功接收到数据。如果有数据需要发送,TCP协议会在发送数据的同时附带ACK来确认对方的数据。如果数据在传输过程中丢失,TCP会进行数据重传。ACK字段是TCP头部必备的,这32个位空着也是空着,那么干脆让除了初始报文段之外的所有报文段的ACK字段都有效。

总结

TCP连接的断开需要通过四次挥手的过程来完成。双方都有能力主动断开连接,并且在断开连接后,各种资源将被释放。四次挥手的过程涉及到双方发送FIN和ACK报文的交互,确保数据的可靠传输和连接的正确关闭。其中,主动关闭方会进入TIME_WAIT状态,等待一段时间来确保对方已经接收到最后的ACK报文。TIME_WAIT状态的存在是为了防止旧连接的数据包干扰新连接,并确保被动关闭方能够正常关闭连接。挥手需要四次的原因是为了确保数据的完整传输和连接的可靠关闭。TIME_WAIT状态等待2倍MSL的时间是为了确保网络中的数据包都已经消失。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
相关文章
|
2月前
|
存储 安全 前端开发
端到端加密:确保数据传输安全的最佳实践
【10月更文挑战第12天】端到端加密(E2EE)是确保数据传输安全的重要手段,通过加密技术保障数据在传输过程中的隐私与完整性,防止第三方窃听和篡改。本文介绍E2EE的工作原理、核心优势及实施步骤,并探讨其在即时通讯、文件共享和金融服务等领域的应用,强调了选择加密协议、密钥管理、数据加密及安全接口设计的重要性,旨在帮助企业和开发者有效保护用户数据,满足数据保护法规要求。
|
4月前
|
安全 网络安全 API
|
4月前
|
网络协议 安全 算法
"网络世界的守护者:一探究竟TCP协议如何确保数据传输的绝对安全与可靠"
【8月更文挑战第20天】传输控制协议(TCP)是网络通信中的核心协议之一,它确保数据包能可靠、有序地从源头传输到目的地。TCP采用三次握手的方式建立连接,并通过序列号、确认应答及超时重传来保障数据传输的准确性。此外,TCP还具备流量控制与拥塞控制功能,避免网络拥塞。虽然TCP在可靠性上表现优异,但在快速传输场景中可能存在局限。深入理解TCP对于网络工程师和开发者至关重要。
72 1
|
4月前
|
网络协议 安全
揭秘TCP背后的秘密:为何三次握手是连接的灵魂,四次挥手是告别的艺术,让数据传输稳如老狗!
【8月更文挑战第4天】TCP为何需三次握手和四次挥手?三次握手确保连接建立时双方均准备好并确认序列号,过程包括:客户端发SYN包;服务器回应SYN+ACK;客户端再回ACK确认,确保可靠通信。四次挥手则确保连接终止时双方能安全、有序地结束数据传输,包括客户端发FIN包;服务器回应ACK并可能继续发送数据;完成后发FIN包;客户端最终确认,确保无数据丢失或状态不一致。
78 9
|
6月前
|
网络协议 API 开发者
无线通信模块通过TCP/IP协议实现与PC端的数据传输
本文介绍了无线通信模块借助TCP/IP协议向PC端传输数据的过程,包括数据封装、发送和接收,并以WIFI模块为例,讨论了在QT平台下实现无线数据传输的方法。通过QTcpSocket类,开发者能轻松建立WIFI模块与PC间的连接。随着无线通信技术的进步,未来将有更多创新应用出现。
|
6月前
|
安全 网络协议 网络安全
程序与技术分享:Android应用安全之数据传输安全
程序与技术分享:Android应用安全之数据传输安全
|
7月前
|
安全 算法 网络协议
HTTPS:如何确保您的网站数据传输安全?
HTTPS:如何确保您的网站数据传输安全?
381 2
|
7月前
|
安全 算法 量子技术
秘钥通信在哪些方面有助于保障数据传输安全?
【5月更文挑战第14天】秘钥通信在哪些方面有助于保障数据传输安全?
37 0
|
7月前
|
SQL 分布式计算 监控
在数据传输服务(DTS)中,要查看每个小时源端产生了多少条数据
【2月更文挑战第32天】在数据传输服务(DTS)中,要查看每个小时源端产生了多少条数据
70 6
|
7月前
|
存储 SQL NoSQL
数据传输DTS同步问题之同步失败如何解决
数据传输服务(DTS)是一项专注于数据迁移和同步的云服务,在使用过程中可能遇到多种问题,本合集精选常见的DTS数据传输问题及其答疑解惑,以助用户顺利实现数据流转。