TCP连接断开:为什么要挥手四次

本文分享自华为云社区《解密TCP连接断开:四次挥手的奥秘和数据传输的安全》,作者: 努力的小雨 。

TCP 连接断开

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

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

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

  • 当客户端打算关闭连接时,它会发送一个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状态没有适当的等待时间或时间过短,延迟的数据包抵达后可能会引发严重的问题。

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

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

保证连接正确关闭

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

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

例如,如果在四次挥手的过程中,客户端发送的最后一个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的时间是为了确保网络中的数据包都已经消失。

点击关注,第一时间了解华为云新鲜技术~

相关推荐
智联物联15 天前
工业 4G 路由器赋能远程医疗,守护生命线
wifi·4g·数据传输·工业4g路由器·智慧医疗·远程医疗·无线通信模块
智联物联25 天前
工业5G路由器让无人机数据传输 “飞” 起来
5g·无人机·工业路由器·数据传输·实时监控·低空经济·无线模块
机器学习是魔鬼1 个月前
从百度云网盘下载数据到矩池云网盘或者服务器内
百度云·数据传输·数据下载·矩池云
RestCloud3 个月前
如何理解ETLCloud在iPaas中的关键角色
etl·数据可视化·数据集成·数据传输·ipaas·集成工具
RestCloud3 个月前
OceanBase数据库结合ETLCloud快速实现数据集成
数据库·oceanbase·etl·分布式存储·数据集成·数据传输
杰克逊的日记3 个月前
CDL数据传输工具
数据库·kafka·数据传输·dts
智联物联3 个月前
物联网中的远距离通信LoRa无线技术
物联网·lora·数据传输·dtu·远距离传输·无线技术·数传电台
ZachOn1y3 个月前
计算机网络:物理层 —— 数据的传输方式
网络·计算机网络·数据传输·物理层·考研必备
智联物联6 个月前
工业5G路由器驱动矿山无人值守及井下监控数据传输
物联网·5g·远程监控·工业路由器·数据传输·户外组网·智慧煤矿
智联物联6 个月前
推动智慧交通建设,边缘计算赋能交通信号灯数据处理与决策能力
5g·边缘计算·数据采集·远程控制·数据传输·工业网关