⬜⬜⬜ 🐰🟧🟨🟩🟦🟪(*^▽^*)欢迎光临 🟧🟨🟩🟦🟪🐰⬜⬜⬜
✏️write in front✏️
📝个人主页:陈丹宇jmu
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
🙉联系作者🙈by QQ:813942269🐧
🌈致亲爱的读者:很高兴你能看到我的文章,希望我的文章可以帮助到你,祝万事顺意🏳️🌈
✉️少年不惧岁月长,彼方尚有荣光在 🏆
📋笔记目录
建议在文章界面右边的导航栏中选择隐藏侧边栏并显示文章目录
《TCP断开连接 ---- 四次挥手知识精讲》
⭐四次挥手的基本概念
💡四次挥手概念简述
四次挥手是指在TCP连接关闭时的一种通信过程,由客户端和服务器之间相互发送的四个步骤组成。 通过四次挥手,双方都能够确认彼此的关闭意图,并完成最后的确认,确保数据的可靠传输和连接的正常关闭。每个阶段的挥手都要等待对方的确认,这样可以确保数据传输的完整性和可靠性。
💡四次挥手具体过程
客户端与服务器端断开连接之前:
客户端 和 服务端都处于ESTABLISHED 状态。
第一次挥手(FIN)
当客户端决定关闭(主动关闭)连接时,它向服务器发送一个带有FIN(Finish)标志的报文段,表示客户端不会再发送数据了,但仍然可以接收数据。
客户端向服务器端发送FIN报文后客户端 由 ESTABLISHED 进入到 FIN_WAIT_1 状态。
第二次挥手(ACK)
服务器接收到客户端的关闭请求后,向客户端发送一个带有ACK(Acknowledgment)标志的报文段,用来确认客户端的关闭请求。服务器可能还有未发送完的数据,因此可以继续发送数据给客户端。
服务器端向客户端回应确认请求关闭的ACK报文后服务器端 由 ESTABLISHED 进入到 CLOSE_WAIT 状态。
客户端接收到服务器端传回的ACK报文后客户端 由 FIN_WAIT_1 进入到 FIN_WAIT_2 状态。
第三次挥手(FIN)
当服务器也准备关闭连接时,它发送一个带有FIN标志的报文段给客户端,表示服务器已经完成了数据的发送。
服务器端向客户端发送FIN报文后服务器端 由 CLOSE_WAIT 进入到 LAST_ACK 状态。
客户端接收到服务器端发送的FIN报文后 客户端由 FIN_WAIT_2 进入到 TIME_WAIT 状态。
第四次挥手(ACK)
客户端接收到服务器的关闭请求后,向服务器发送一个带有ACK标志的报文段,用来确认服务器的关闭请求。双方交换完这最后一个ACK报文段后,TCP连接彻底关闭。
服务器端的状态由 LAST_ACK 进入到 CLOSED 状态。
等待2MSL
客户端发出最后的ACK确认报文时,并不能确定服务器端能够收到该段报文。所以客户端在发送完ACK确认报文之后,会设置一个时长为2MSL的计时器。2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长。
客户端在等待2MLS时长后,如果没有收到服务器重传的FIN报文,客户端则认为最后一次挥手的确认报文被服务器顺利接收了。客户端的状态由 TIME_WAIT 进入到 CLOSED 状态。
💡四次挥手过程状态解读
客户端四次挥手过程状态解读
ESTABLISHED
这个容易理解了,表示连接已经建立了。
FIN_WAIT_1
这个状态要好好解释一下,其实 FIN_WAIT_1 和 FIN_WAIT_2 状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态。
当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。
FIN_WAIT_2
上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。
TIME_WAIT
表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
服务器四次挥手过程状态解读
ESTABLISHED
这个容易理解了,表示连接已经建立了。
CLOSE_WAIT
这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是查看你是否还有数据发送给对方,如果没有的话,那么你也就可以close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。
LAST_ACK
这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。
四次挥手过程中特殊状态解读
CLOSING
这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却收到了对方的FIN报文。
什么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也就会出现CLOSING状态,表示双方都正在关闭SOCKET连接。
⭐套接字和四次挥手的关联
套接字和四次挥手是两个在网络通信中相关的概念。
套接字(Socket)是应用层和传输层之间的接口,它提供了应用程序与网络之间进行数据传输的方法。通过套接字,应用程序可以创建、发送和接收数据报文。
四次挥手(Four-Way Handshake)是用于关闭一个 TCP 连接的过程。在客户端和服务器之间的通信结束时,双方需要进行四次挥手来正确地关闭连接,以确保双方都完成了数据的传输和确认。
套接字是应用程序和网络之间进行数据传输的接口,而四次挥手是用于关闭 TCP 连接的过程,在这个过程中套接字被用来发送和接收关于连接关闭的报文段。
具体来说,套接字在建立 TCP 连接时起到了关键的作用。当客户端和服务器建立连接时,它们会创建相应的套接字并绑定到特定的 IP 地址和端口上。通过这些套接字,双方可以进行数据的传输和通信。
当双方决定关闭连接时,它们会执行四次挥手的过程。这个过程包括以下步骤:
- 客户端发送一个关闭连接请求给服务器,进入 FIN-WAIT-1 状态。
- 服务器收到请求后发送一个确认,并进入 CLOSE-WAIT 状态。
- 服务器关闭发送数据的能力后,发送一个关闭连接请求给客户端,进入 LAST-ACK 状态。
- 客户端收到请求后发送一个确认,并进入 TIME-WAIT 状态。在一段时间后,客户端关闭连接,并且服务器也关闭连接。
在这个过程中,套接字被用来发送和接收用于关闭连接的报文段,参与了整个四次挥手过程的通信。
⭐四次挥手报文解析
💡第一次挥手的报文解析
第一次挥手报文摘要Info
TCP 60 23 → 12660 [FIN, PSH, ACK] Seq=112 Ack=58 Win=4071 Len=0
第一次挥手的报文解析:
根据提供的 TCP 报文段信息,我们可以分析如下:
- 源端口号:23
- 目标端口号:12660
- 报文标识符:60
- TCP 标志:FIN(结束)、PSH(推送)、ACK(确认)
- 序列号(Seq):112,表示发送方发送的数据字节流中的第一个字节的序号
- 确认号(Ack):58,表示接收方期望下一个字节的序号
- 窗口大小(Win):4071,表示接收方的接收窗口大小
- 长度(Len):0,表示该报文中的数据长度为零
第一次挥手的完整解析
根据报文中的 FIN、PSH、ACK 标志,我们可以得出以下解释:
- FIN 标志表示发送方不再发送数据,并希望关闭连接。
- PSH 标志表示请求接收方尽快将数据传递给应用层,而不是等到缓冲区填满再传递。
- ACK 标志表示确认接收方已经正确地接收到了之前的数据。
综上所述,该报文是一个包含FIN、PSH和ACK标志的TCP报文段,用于向目标端口号为12660的服务器发送连接释放请求,并确认之前的数据已正确接收。
💡第二次挥手的报文解析
第二次挥手报文摘要Info
TCP 60 12660 → 23 [ACK] Seq=58 Ack=113 Win=4017 Len=0
第二次挥手的报文解析:
根据提供的 TCP 报文段信息,我们可以进行如下分析:
- 源端口号:12660
- 目标端口号:23
- 报文标识符:60
- TCP 标志:ACK(确认)
- 序列号(Seq):58,表示发送方发送的数据字节流中的第一个字节的序号
- 确认号(Ack):113,表示接收方期望下一个字节的序号
- 窗口大小(Win):4017,表示接收方的接收窗口大小
- 长度(Len):0,表示该报文中的数据长度为零
第二次挥手的完整解析
根据报文中的 ACK 标志,我们可以得出以下解释:
- ACK 标志表示接收方确认已经正确地接收到之前的数据。
综上所述,该报文是一个包含ACK标志的TCP报文段,用于向目标端口号为23的客户端发送确认,确认之前的数据已经正确接收。
💡第三次挥手的报文解析
第三次挥手报文摘要Info
TCP 60 12660 → 23 [FIN, PSH, ACK] Seq=58 Ack=113 Win=4017 Len=0
第三次挥手的报文解析:
根据提供的 TCP 报文段信息,我们可以进行如下分析:
- 源端口号:12660
- 目标端口号:23
- 报文标识符:60
- TCP 标志:FIN(结束)、PSH(推送)、ACK(确认)
- 序列号(Seq):58,表示发送方发送的数据字节流中的第一个字节的序号
- 确认号(Ack):113,表示接收方期望下一个字节的序号
- 窗口大小(Win):4017,表示接收方的接收窗口大小
- 长度(Len):0,表示该报文中的数据长度为零
第三次挥手的完整解析
根据报文中的 FIN、PSH 和 ACK 标志,我们可以得出以下解释:
- FIN 标志表示发送方不再发送数据,并希望关闭连接。
- PSH 标志表示请求接收方尽快将数据传递给应用层,而不是等到缓冲区填满再传递。
- ACK 标志表示确认接收方已经正确地接收到了之前的数据。
综上所述,该报文是一个包含 FIN、PSH 和 ACK 标志的 TCP 报文段,用于向目标端口号为 23 的客户端发送连接释放请求,并确认之前的数据已正确接收。
💡第四次挥手的报文解析
第四次挥手报文摘要Info
TCP 60 23 → 12660 [ACK] Seq=113 Ack=59 Win=4071 Len=0
第四次挥手的报文解析:
根据提供的 TCP 报文段信息,我们可以进行如下分析:
- 源端口号:23
- 目标端口号:12660
- 报文标识符:60
- TCP 标志:ACK(确认)
- 序列号(Seq):113,表示发送方发送的数据字节流中的第一个字节的序号
- 确认号(Ack):59,表示接收方期望下一个字节的序号
- 窗口大小(Win):4071,表示接收方的接收窗口大小
- 长度(Len):0,表示该报文中的数据长度为零
第四次挥手的完整解析
根据报文中的 ACK 标志,我们可以得出以下解释:
- ACK 标志表示接收方确认已经正确地接收到之前的数据。
综上所述,该报文是一个包含 ACK 标志的 TCP 报文段,用于向目标端口号为 12660 的服务器发送确认,确认之前的数据已经正确接收。
⭐四次挥手面试题精选
(1)是否可以在两次握手后直接关闭连接而无需进行四次挥手?
不能在两次握手后直接关闭连接而无需进行四次挥手。这是因为TCP协议的设计需要确保数据的可靠传输和连接的完整性。
在TCP连接的关闭过程中,四次挥手是必要的。关闭连接时,客户端和服务器之间仍然可能存在未发送或未接收的数据。如果在两次握手后直接关闭连接,就会导致未发送或未接收的数据丢失,可能会造成数据的丢失或不完整。
通过四次挥手,可以保证双方都完成了数据的传输和确认。在四次挥手的步骤中,双方依次发送关闭连接请求和确认,并最终关闭连接。双方的关闭请求和确认的交互,以及最后的关闭步骤,确保了数据的完整性和可靠性。
此外,四次挥手中的TIME_WAIT状态也起到了重要的作用。在连接关闭后,客户端进入TIME_WAIT状态,该状态持续一段时间。这个等待时间是为了确保网络中所有延迟或重组的数据报文都能被处理完毕,以免对后续的连接造成干扰。TIME_WAIT状态的存在可以避免潜在的数据混乱和冲突。
因此,在TCP连接关闭时,进行四次挥手是必要的,以保证数据的可靠传输和连接的完整性。
(2)在四次挥手中,为什么有个TIME_WAIT状态?它的作用是什么?
在四次挥手(TCP连接的关闭过程)中,TIME_WAIT状态是指主动关闭连接的一方进入的状态,它持续一段时间后才能结束。TIME_WAIT状态的作用有以下几个方面:
-
确保可靠的连接关闭:TIME_WAIT状态允许先前的连接在网络中完全消失,确保双方都可以安全地关闭连接。在此期间,如果对方发送来的最后一个ACK丢失或延迟,那么主动关闭的一方仍然可以收到重发的ACK并响应,从而避免了出现错误的连接复用,确保了可靠的连接关闭。
-
防止旧数据包干扰:主动关闭连接方进入TIME_WAIT状态后,会拒绝接收具有相同源IP和目的IP的新数据包,并阻止可能残留在网络中、延迟到达的旧数据包干扰新建立的连接。这样可以确保后续建立的连接不会受到过去连接的影响。
-
允许端口重用:TIME_WAIT状态还允许操作系统回收关闭连接的端口,使得同一端口可以被其他新连接使用而不会出现冲突。如果没有TIME_WAIT状态,端口就无法立即被重用,会导致端口资源浪费和连接建立的延迟。
总之,TIME_WAIT状态在TCP连接关闭过程中的作用是确保可靠的连接关闭、防止旧数据包干扰以及允许端口重用。它是为了提高网络通信的可靠性和效率而引入的机制。
(3)为什么客户端在TIME-WAIT阶段要等2MSL?
为的是确认服务器端是否收到客户端发出的 ACK 确认报文,当客户端发出最后的 ACK 确认报文时,并不能确定服务器端能够收到该段报文。
所以客户端在发送完 ACK 确认报文之后,会设置一个时长为 2MSL 的计时器。
MSL 指的是 Maximum Segment Lifetime:一段 TCP 报文在传输过程中的最大生命周期。
2MSL 即是服务器端发出为 FIN 报文和客户端发出的 ACK 确认报文所能保持有效的最大时长。
服务器端在 1MSL 内没有收到客户端发出的 ACK 确认报文,就会再次向客户端发出 FIN 报文:
如果客户端在 2MSL 内,再次收到了来自服务器端的 FIN 报文,说明服务器端由于各种原因没有接收到客户端发出的 ACK 确认报文。
客户端再次向服务器端发出 ACK 确认报文,计时器重置,重新开始 2MSL 的计时。
否则客户端在 2MSL 内没有再次收到来自服务器端的 FIN 报文,说明服务器端正常接收了 ACK 确认报文,客户端可以进入 CLOSED 阶段,完成“四次挥手”。
所以,客户端要经历时长为 2SML 的 TIME-WAIT 阶段;这也是为什么客户端比服务器端晚进入 CLOSED 阶段的原因。
🏳️🌈附录
流式套接字的建立
数据报套接字建立
套接字在TCP连接和关闭中的状态过程
🚩结尾
考虑到阅读篇幅,更多实验内容参考本专栏中的其他文章
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
🌈写给读者:很高兴你能看到我的文章,希望我的文章可以帮助到你,祝万事顺意🏳️🌈