🔍 开发者资源导航 🔍 |
---|
🏷️ 博客主页: 个人主页 |
📚 专栏订阅: JavaEE全栈专栏 |
前言
在网络通信的底层世界中,TCP协议如同一位严谨的工程师,用精妙的机制确保每一字节数据都能准确送达。三次握手与四次挥手就是这位工程师最得意的作品,它们不仅构建了可靠的连接通道,更隐藏着许多令人惊叹的设计智慧。
🔍 本期核心内容:
🔹三次握手的精妙博弈:为什么不是两次或四次?SYN报文中的初始序列号有何玄机?
🔹四次挥手的优雅告别:TIME_WAIT状态真的是在浪费资源吗?CLOSE_WAIT过多该如何排查?
🔹异常情况的实战分析:SYN Flood攻击防御、RST暴力断开、握手失败的常见原因
📌 这些机制为何如此重要?
- 三次握手确保通信双方具备完整的收发能力,避免"单工通信"的尴尬
- 四次挥手保证数据能够完整传输,防止"半途而废"的数据丢失
- TIME_WAIT状态是TCP协议的最后一道防线,防止旧连接的"幽灵数据"干扰新连接
建立连接(三次握手)
在TCP协议中,连接的建立是通过“三次握手”来进行的,而所谓的“握手”只是双方进行了一次打招呼,并不会涉及到业务数据,但是连接双方可以通过握手向对方传递一些关键的信息来保证连接的顺利。
建立流程
在TCP协议的报头中标志位SYN为1表示该报文是一个同步报文,告诉对方你把我的ip端口号保存一下,我也把你的保存一下,而建立连接的过程则是双方各自发送一个同步报文,并且接收到后返回给对方ACK。
🧠SYN是同步的意思,在TCP中指的是“数据上的同步”。
🤔三次握手为什么有四次过程呢❓
在建立连接过程中接受方的ack和sync均是由内核控制的,因此为了简化流程,它们会合并成一个操作,所以它才称之为“三次握手”而不是“四次握手”。
📌在三次握手过程中经过的状态
CLOSED:不存在的状态,tcp连接还没有开始。
LISTEN:启动服务器new ServerSocket的时候,就会进入LISTEN状态,该状态表明服务器已经准备好了随时可以进行连接。
SYN_SENT:同步已发送。
SYN_RCVD:同步已接收。
ESTABLISHED:已经连接了的,服务器和客户端已经建立连接,接下来可以传输数据了。
握手的作用
🔹三次握手相当于“投石问路”,先初步试探网络的通信链路是否通常。
🔹验证通信双方的发送能力和接受能力是否也正常。
三次握手但凡少一次双方都会缺少信息,因此不能是“两次握手”。
🔹三次握手过程中,可以协商一些关键信息,例如:初始序列号。
在连接时,可能会因为某些原因上次连接的数据到本次才传递过来,因此为了避免“前朝的人”影响当前的“内政”,序号的设定每次都会相差很远,这样如果遇见了和本次初始序列号差值大的数据,就会直接抛弃掉。
断开连接(四次挥手)
断开连接和建立连接相似,通过四次的信息和对方说再见,在断开的过程中没有太多的操作,仅仅是让双方保存的信息删除掉。
断开流程
断开连接和建立连接是一个相似的流程,双方互相发送标记为FIN为1的数据报,告诉对方把我的信息删除掉。
断开连接不能用客户端和服务端一词,因为双方都可以主动断开连接,但是建立连接一定是客户端主动发起的。
🤔四次挥手的过程可以合并吗❓
大多数情况下都不可以,在建立连接时ack+syn都是由内核操控的,因此可以保证同一时机发送。而断开连接时,B的ack是内核操控发送的,但是B的fin发送是B由应用程序决定的(调用Socket.close的时候触发),而应用程序的实现怎么写都有可能,无法保证同一时机发送,因此不可以看做是一起的。
而小概率情况,例如在延时应答的条件下,恰巧它们被一起发送了,因此总的来说还是“四次挥手”。
📌在四次挥手过程中经过的状态
这里我们只讲两个常用的状态:
- CLOSE_WAIT:被动发起FIN的那方进入CLOSE_WAIT状态,正常开发中应该是看不到的,在感知到断开后原则上应该尽快调用close方法。
- TIME_WAIT:主动发起FIN的那方进入该状态,该状态不会立即释放连接,等待一段时间后再释放。
🔍TIME_WAIT作用:
TIME_WAIT是为了避免丢包的情况,假设最后一次的ack发生了丢包的情况,因为会触发超时重传机制,会再次发送FIN到对端,而如果对端连接已经彻底关闭就无法正常接受,因此TIME_WAIT状态就是为了避免这种情况的发生,多等待一会,确认对方不会重传FIN后再释放。
🚨异常情况
如果A主动发送连接后,B迟迟没有回应,A就会主动释放连接,而对于B因为没有收到FIN的原因还是会暂存A的信息,但是无法正常通信。
挥手的作用
🔹可靠关闭双向数据流
TCP 是全双工的,双方可能仍有数据需要发送或接收。四次挥手确保双方确认对方已无数据需要发送,避免数据丢失。
🔹处理残留数据
被动方收到第一个
FIN
后,可能仍需发送剩余数据(如未传完的响应),通过ACK
和后续FIN
分阶段关闭。
🔹防止旧连接干扰
通过
TIME_WAIT
状态(主动方等待 2MSL),确保网络中残留的旧报文失效,避免被新连接误接收。
下期预告
在《TCP/UDP协议深度解析(三):TCP的流量艺术》中,我们将探索:
- 滑动窗口:如何实现高效批量传输的"流水线作业"?
- 流量控制:接收端如何优雅地说"我吃不下了"?
- 拥塞控制:网络拥堵时的智能调速策略
- 延时应答与捎带应答:TCP协议中的"时间管理大师"