在网络通信的世界里,TCP协议就像是两个人之间的礼貌对话。当你想要与某人建立对话时,你会先打招呼确认对方能听到你的声音;当对话结束时,你也会礼貌地告别。TCP的三次握手和四次挥手就是这样的”网络礼仪”。
什么是TCP连接?
TCP(传输控制协议)是一种可靠的、面向连接的传输层协议。它确保数据能够准确、有序地从发送方传输到接收方。要实现这种可靠传输,TCP需要在通信双方之间建立连接,这就是”三次握手”的作用;当通信结束时,需要优雅地关闭连接,这就是”四次挥手”的作用。
TCP报文段中的重要标志位
在深入了解握手和挥手过程之前,我们需要先了解TCP报文段中的几个关键标志位:
主要TCP标志位及其作用
| 标志位 |
全称 |
作用 |
| SYN |
Synchronize |
同步标志,用于建立连接时的序号同步 |
| ACK |
Acknowledgment |
确认标志,表示确认号字段有效 |
| FIN |
Finish |
结束标志,表示发送方数据发送完毕,要求释放连接 |
| RST |
Reset |
重置标志,用于重置连接 |
| PSH |
Push(该文章未讲解) |
推送标志,要求立即将数据推送给应用层 |
| URG |
Urgent(该文章未讲解) |
紧急标志,表示紧急指针字段有效 |
TCP连接状态详解
TCP连接在其生命周期中会经历多种状态,理解这些状态对于掌握握手和挥手过程至关重要:
主要连接状态(建议直接看下方的过程,如果不懂再回来查阅)
- CLOSED:初始状态,表示没有连接
- LISTEN:服务器监听状态,等待客户端连接请求
- SYN_SENT:客户端发送SYN后的状态,等待服务器确认
- SYN_RCVD:服务器收到SYN并发送SYN+ACK后的状态
- ESTABLISHED:连接建立成功,可以进行数据传输
- FIN_WAIT_1:主动关闭方发送FIN后的状态
- FIN_WAIT_2:主动关闭方收到ACK后的状态
- CLOSE_WAIT:被动关闭方收到FIN后的状态
- LAST_ACK:被动关闭方发送FIN后的状态
- TIME_WAIT:主动关闭方收到FIN并发送ACK后的状态
三次握手:建立连接的过程
三次握手是TCP建立连接的过程
三次握手流程图
1 2 3 4 5 6 7 8 9
| 客户端 服务器 | | |-------SYN seq=x------->| (第一次握手) | | |<--SYN+ACK seq=y,ack=x+1| (第二次握手) | | |----ACK seq=x+1,ack=y+1>| (第三次握手) | | | 连接建立完成 |
|
三次握手状态转换图
1 2 3 4 5
| 客户端状态变化: CLOSED → SYN_SENT → ESTABLISHED
服务器状态变化: LISTEN → SYN_RCVD → ESTABLISHED
|
握手过程详解
第一次握手(SYN)
- 客户端 → 服务器:发送SYN报文
- 客户端状态:CLOSED → SYN_SENT
- 服务器状态:LISTEN(保持不变)
- 信号含义:
- 对客户端:表示”我想和你建立连接”
- 对服务器:表示”客户端具有发送能力,请求建立连接”
第二次握手(SYN+ACK)
- 服务器 → 客户端:发送SYN+ACK报文
- 服务器状态:LISTEN → SYN_RCVD
- 客户端状态:SYN_SENT(保持不变)
- 信号含义:
- 对服务器:表示”我同意建立连接,同时我也想和你建立连接”
- 对客户端:表示”服务器具有接收和发送能力,同意建立连接”
第三次握手(ACK)
- 客户端 → 服务器:发送ACK报文
- 客户端状态:SYN_SENT → ESTABLISHED
- 服务器状态:SYN_RCVD → ESTABLISHED
- 信号含义:
- 对客户端:表示”确认收到你的同意,连接建立完成”
- 对服务器:表示”客户端具有接收能力,连接确认完成”
为什么需要三次握手?
- 确认双方的收发能力:
- 第一次握手:确认客户端发送能力
- 第二次握手:确认服务器接收和发送能力
- 第三次握手:确认客户端接收能力
- 防止历史连接:避免因网络延迟导致的无效连接请求
- 同步序列号:确保数据传输的有序性和可靠性
四次挥手:关闭连接的过程
四次挥手是TCP关闭连接的过程
四次挥手流程图
1 2 3 4 5 6 7 8 9 10 11
| 客户端 服务器 | | |-------FIN seq=x------->| (第一次挥手) | | |<----ACK seq=y,ack=x+1--| (第二次挥手) | | |<----FIN seq=z,ack=x+1--| (第三次挥手) | | |----ACK seq=x+1,ack=z+1>| (第四次挥手) | | | 连接关闭完成 |
|
四次挥手状态转换图
1 2 3 4 5
| 主动关闭方(客户端)状态变化: ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
被动关闭方(服务器)状态变化: ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED
|
挥手过程详解
第一次挥手(FIN)
- 客户端 → 服务器:发送FIN报文
- 客户端状态:ESTABLISHED → FIN_WAIT_1
- 服务器状态:ESTABLISHED(保持不变)
- 信号含义:
- 对客户端:表示”我的数据发送完了,准备关闭连接”
- 对服务器:表示”客户端请求关闭连接,但服务器可能还有数据要发送”
第二次挥手(ACK)
- 服务器 → 客户端:发送ACK报文
- 服务器状态:ESTABLISHED → CLOSE_WAIT
- 客户端状态:FIN_WAIT_1 → FIN_WAIT_2
- 信号含义:
- 对服务器:表示”我知道你要关闭了,但我可能还有数据要发送”
- 对客户端:表示”服务器收到了关闭请求,请等待”
第三次挥手(FIN)
- 服务器 → 客户端:发送FIN报文
- 服务器状态:CLOSE_WAIT → LAST_ACK
- 客户端状态:FIN_WAIT_2(保持不变)
- 信号含义:
- 对服务器:表示”我的数据也发送完了,可以关闭连接”
- 对客户端:表示”服务器准备关闭连接”
第四次挥手(ACK)
- 客户端 → 服务器:发送ACK报文
- 客户端状态:FIN_WAIT_2 → TIME_WAIT → CLOSED
- 服务器状态:LAST_ACK → CLOSED
- 信号含义:
- 对客户端:表示”确认关闭,连接彻底结束”
- 对服务器:表示”客户端确认关闭,可以释放资源”
为什么需要四次挥手?
- TCP是全双工通信:需要分别关闭两个方向的数据传输
- 数据完整性:确保双方都完成了数据传送
- 资源释放:确保双方都能正确释放连接资源
TIME_WAIT状态的作用
客户端在发送最后一个ACK后会进入TIME_WAIT状态,等待2MSL(Maximum Segment Lifetime)时间,这样做的原因:
- 确保最后的ACK被服务器收到:如果ACK丢失,服务器会重发FIN
- 确保网络中的延迟报文消失:避免影响新的连接
常见问题与优化
1. 大量TIME_WAIT状态的处理
- 调整系统参数:
net.ipv4.tcp_tw_reuse、net.ipv4.tcp_tw_recycle
- 使用连接池复用连接
- 调整应用程序的连接管理策略
2. SYN攻击防护
- 设置SYN队列大小限制
- 启用SYN Cookie机制
- 使用防火墙过滤异常请求
3. 连接超时处理
- 设置合适的连接超时时间
- 实现重连机制
- 使用健康检查机制
总结
TCP的三次握手和四次挥手是网络编程中的基础概念,理解这些过程有助于:
- 诊断网络问题:通过分析连接状态判断问题所在
- 优化应用性能:合理管理连接的建立和释放
- 提高系统稳定性:正确处理各种异常情况