## 1. 三次握手详细流程与状态变迁### 1.1 握手目的TCP三次握手是建立可靠连接的过程主要目的- 确认双方收发能力正常- 同步双方序列号- 协商连接参数### 1.2 详细流程**第一次握手SYN**客户端 → 服务器TCP段- Source Port: 12345 (客户端随机端口)- Destination Port: 80 (HTTP服务端口)- Sequence Number: 1000 (客户端初始序列号ISN)- Flags: SYN (同步标志位)- Window Size: 65535状态变化客户端CLOSED → SYN_SENT**第二次握手SYNACK**服务器 → 客户端TCP段- Source Port: 80- Destination Port: 12345- Sequence Number: 2000 (服务器初始序列号ISN)- Acknowledgment Number: 1001 (确认客户端序列号1)- Flags: SYNACK (同步确认)状态变化服务器LISTEN → SYN_RCVD**第三次握手ACK**客户端 → 服务器TCP段- Source Port: 12345- Destination Port: 80- Sequence Number: 1001- Acknowledgment Number: 2001 (确认服务器序列号1)- Flags: ACK (确认标志位)状态变化客户端SYN_SENT → ESTABLISHED服务器SYN_RCVD → ESTABLISHED### 1.3 状态变迁图客户端状态CLOSED → SYN_SENT → ESTABLISHED服务器状态CLOSED → LISTEN → SYN_RCVD → ESTABLISHED## 2. 为什么要三次握手两次为什么不行### 2.1 两次握手的问题**场景分析**情况1延迟的SYN报文客户端发送SYN → 网络延迟 → 服务器回复SYNACK → 客户端已超时关闭延迟的SYN到达服务器 → 服务器以为是新连接 → 发送SYNACK如果两次握手就建立连接服务器会维护一个不存在的连接情况2序列号不同步只有两次握手服务器无法确认客户端收到了自己的序列号可能导致数据传输时序列号不匹配### 2.2 三次握手的必要性**确保双向通信能力**第一次握手客户端→服务器证明客户端能发第二次握手服务器→客户端证明服务器能收能发第三次握手客户端→服务器证明客户端能收只有三次握手才能确认双方收发能力都正常**序列号同步**三次握手过程中双方交换序列号并确认确保双方对数据位置有共同认知为后续可靠传输奠定基础### 2.3 实例两次握手的风险假设只需要两次握手步骤1客户端发送SYN(seq1000)步骤2服务器发送SYNACK(seq2000, ack1001)连接建立问题如果步骤1的SYN延迟到达服务器会建立连接但客户端可能已经关闭造成资源浪费服务器会一直等待客户端数据直到超时## 3. 四次挥手为什么要TIME_WAIT### 3.1 四次挥手流程**第一次挥手FIN**主动关闭方 → 被动关闭方Flags: FINSequence Number: 5000**第二次挥手ACK**被动关闭方 → 主动关闭方Flags: ACKAcknowledgment Number: 5001**第三次挥手FIN**被动关闭方 → 主动关闭方Flags: FINSequence Number: 6000**第四次挥手ACK**主动关闭方 → 被动关闭方Flags: ACKAcknowledgment Number: 6001### 3.2 TIME_WAIT的作用**等待最后一个ACK被确认**主动关闭方发送最后一个ACK后进入TIME_WAIT状态如果被动关闭方没收到ACK会重传FINTIME_WAIT状态确保有时间重传丢失的ACK**防止旧连接的延迟报文干扰新连接**网络中可能存在延迟的TCP报文TIME_WAIT等待足够长时间让这些报文过期确保新连接不会收到旧连接的报文### 3.3 TIME_WAIT状态特点持续时间2MSLMaximum Segment Lifetime典型值1-2分钟占用资源端口号在TIME_WAIT期间无法被重用## 4. TIME_WAIT为什么是2MSL### 4.1 MSL的定义MSLMaximum Segment Lifetime一个TCP报文在网络中的最大生存时间。RFC标准建议MSL为2分钟实际实现中常见30秒、1分钟### 4.2 为什么是2倍MSL**等待往返时间**发送最后一个ACK后最多等待MSL时间让ACK到达对方如果对方没收到ACK会在MSL时间内重传FIN主动关闭方需要再等待MSL时间接收重传的FIN总共需要2MSL时间**公式说明**2MSL MSL(ACK传输) MSL(可能的FIN重传)确保1. 最后一个ACK有足够时间到达对方2. 对方重传的FIN有足够时间到达3. 所有延迟报文都已过期### 4.3 实例2MSL的必要性场景最后一个ACK丢失步骤1主动关闭方发送ACK(ack6001)步骤2ACK丢失步骤3被动关闭方超时重传FIN(seq6000)步骤4主动关闭方在TIME_WAIT期间收到FIN步骤5主动关闭方重传ACK(ack6001)步骤6被动关闭方收到ACK连接正常关闭如果没有TIME_WAIT或时间不足步骤4主动关闭方已关闭无法接收FIN步骤5被动关闭方无法收到ACK结果被动关闭方资源无法释放## 5. SYN泛洪攻击与半连接队列### 5.1 SYN泛洪攻击原理攻击者发送大量SYN请求但不完成三次握手攻击流程1. 攻击者发送SYN(seqX)2. 服务器回复SYNACK(seqY, ackX1)3. 攻击者不发送ACK4. 服务器进入SYN_RCVD状态等待ACK5. 大量半连接耗尽服务器资源### 5.2 半连接队列**定义**服务器维护的等待三次握手完成的连接队列队列满时新的SYN请求会被丢弃或拒绝**队列状态**SYN_RCVD状态的连接在半连接队列中等待第三次握手的ACK超时时间通常为1分钟左右### 5.3 防御措施**SYN Cookies**原理服务器不保存半连接状态使用cookie代替队列cookie hash(客户端IP, 客户端端口, 服务器IP, 服务器端口, 时间戳)流程1. 收到SYN计算cookie作为序列号2. 发送SYNACK(seqcookie)3. 收到ACK时验证cookie4. 验证通过才建立连接**增加队列长度**调整内核参数tcp_max_syn_backlog - 半连接队列最大长度tcp_syncookies - 启用SYN Cookiestcp_synack_retries - SYNACK重传次数**限流和过滤**- 使用防火墙限制每秒SYN数量- 基于源IP限流- 识别攻击流量并阻断### 5.4 实例SYN泛洪攻击与防御攻击场景攻击者每秒发送10000个SYN请求服务器半连接队列长度1024队列很快填满正常用户无法建立连接防御后启用SYN Cookies服务器不再维护半连接队列攻击者的SYN请求无法消耗资源正常用户可以正常连接## 6. 总结TCP三次握手和四次挥手是保证可靠连接的核心机制1. **三次握手**确认双方通信能力同步序列号2. **两次握手不够**无法确认双向通信能力存在安全风险3. **TIME_WAIT**等待最后ACK确认防止旧报文干扰4. **2MSL**确保往返时间内的报文都能处理5. **SYN泛洪防御**使用SYN Cookies和队列优化理解这些机制对于网络编程、故障排查和安全防护至关重要。在实际应用中需要合理配置系统参数平衡性能和安全性。