TCP三次握手是建立可靠网络连接的关键步骤,第三次握手(客户端发送ACK确认)的存在主要有以下原因:
1. 防止历史重复连接导致的资源浪费
-
场景:若客户端发送的旧SYN报文(因网络延迟滞留)到达服务器,服务器会误认为是新连接请求,返回SYN-ACK并分配资源。
-
问题:若仅有两次握手,服务器直接进入连接状态,但客户端可能已放弃该请求,导致服务器资源被长期占用(如内存、端口)。
-
解决:第三次ACK确认让客户端有机会判断连接请求是否过时。若客户端已发起新连接,会忽略旧SYN触发的SYN-ACK,避免服务器无效等待。
2. 确保双方收发能力与序列号同步
-
第一次握手:客户端发送SYN(携带自身初始序列号),证明客户端发送能力正常。
-
第二次握手:服务器回复SYN-ACK(确认客户端序列号+1,并携带自身序列号),证明服务器收发能力正常。
-
第三次握手:客户端发送ACK(确认服务器序列号+1),最终验证客户端接收能力正常。只有三次握手后,双方均确认彼此的收发能力与序列号同步,避免数据错乱。
3. 避免资源被半连接占用
-
若只有两次握手,服务器在发送SYN-ACK后立即进入连接状态。若客户端不响应,服务器需等待超时才能释放资源,易受SYN洪泛攻击(恶意发送大量SYN但不回复ACK)。
-
三次握手迫使服务器在收到第三次ACK后才分配全量资源(如连接队列),结合SYN Cookie等机制,可有效缓解此类攻击。
示例:两次握手的风险
假设客户端发送SYN(序列号=100)建立连接,但该报文滞留。客户端超时重传新SYN(序列号=200),正常完成通信后,旧SYN到达服务器:
-
两次握手:服务器响应SYN-ACK(确认号=101)并直接进入连接状态,等待客户端发送数据。但客户端早已使用新序列号通信,导致服务器持续等待无效数据,浪费资源。
-
三次握手:服务器发送SYN-ACK后,需等待客户端的ACK(确认号=101)。客户端发现确认号不匹配(当前序列号=200),会发送RST重置连接,服务器及时释放资源。
总结
第三次握手通过客户端对服务器序列号的最终确认,确保:
-
双方收发能力可靠;
-
初始序列号同步;
-
历史连接请求不会误占资源;
-
抵御部分拒绝服务攻击。
这是TCP实现可靠传输、避免资源浪费与数据混乱的核心设计。