TCP 是一种面向连接的可靠传输协议,通过 三次握手 建立连接,通过 四次挥手 释放连接。
一、三次握手(建立连接)
过程
第一次握手(SYN=1, ACK=0)
• 客户端发送SYN报文(SYN=1, seq=x),进入SYN_SENT状态。
• 目的:请求建立连接,并告知初始序列号x。
第二次握手(SYN=1, ACK=1)
• 服务器收到SYN后,回复SYN+ACK报文(SYN=1, ACK=1, seq=y, ack=x+1),进入SYN_RCVD状态。
• 目的:
◦ 确认客户端的SYN(ack=x+1)。
◦ 请求建立连接(SYN=1),并告知自己的初始序列号y。
第三次握手(ACK=1)
• 客户端收到SYN+ACK后,发送ACK报文(ACK=1, seq=x+1, ack=y+1),进入ESTABLISHED状态。
• 服务器收到后也进入ESTABLISHED状态,连接建立成功。
• 目的:确认服务器的SYN(ack=y+1),完成双向确认。
为什么需要三次握手?
防止历史重复连接初始化造成资源浪费
• 如果只有两次握手,客户端可能因网络延迟重发SYN,服务器误认为这是一个新连接,导致资源浪费(如分配缓冲区)。
• 三次握手确保双方都确认彼此的发送和接收能力正常。
同步双方的初始序列号(ISN)
• TCP 使用序列号保证数据有序传输,三次握手让双方交换并确认各自的seq。
可靠建立连接
• 三次握手确保双方都能正确收发数据,避免单向通信问题。
二、四次挥手(释放连接)
过程
第一次挥手(FIN=1, ACK=0)
• 主动方(如客户端)发送FIN报文(FIN=1, seq=u),进入FIN_WAIT_1状态。
• 目的:请求关闭连接。
第二次挥手(ACK=1)
• 被动方(如服务器)收到FIN后,回复ACK报文(ACK=1, seq=v, ack=u+1),进入CLOSE_WAIT状态。
• 目的:确认客户端的关闭请求,并通知应用层准备关闭。
第三次挥手(FIN=1, ACK=1)
• 被动方(服务器)发送FIN报文(FIN=1, ACK=1, seq=w, ack=u+1),进入LAST_ACK状态。
• 目的:请求关闭自己的方向连接。
第四次挥手(ACK=1)
• 主动方(客户端)收到FIN后,回复ACK报文(ACK=1, seq=u+1, ack=w+1),进入TIME_WAIT状态。
• 被动方收到ACK后进入CLOSED状态。
• 主动方等待 2MSL(最大报文生存时间)后进入CLOSED状态。
• 目的:确保被动方的FIN被正确接收,防止旧数据干扰。
为什么需要四次挥手?
TCP 是全双工协议
• 连接是双向的,双方都需要独立关闭自己的发送通道。
• 第一次挥手关闭 A→B 的发送,第二次挥手确认;第三次挥手关闭 B→A 的发送,第四次挥手确认。
确保数据完全传输
• 被动方(如服务器)可能在收到FIN后仍有数据未发送完,需要先处理完数据再关闭(进入CLOSE_WAIT状态)。
防止旧数据干扰(TIME_WAIT)
• 主动方等待 2MSL(约 1-4 分钟)确保最后一个ACK能被接收,避免旧连接的延迟数据包干扰新连接。
三、总结对比
阶段三次握手四次挥手
目的建立连接释放连接
次数3 次4 次
原因防止历史连接、同步 ISN全双工关闭、确保数据完整
状态变化客户端:CLOSED → SYN_SENT → ESTABLISHED
服务器:CLOSED → LISTEN → SYN_RCVD → ESTABLISHED
主动方:ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
被动方:ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED
关键点
• 三次握手 确保双方收发能力正常,并同步初始序列号。
• 四次挥手 确保全双工连接安全关闭,避免数据丢失。
• TIME_WAIT 是 TCP 可靠性的重要保障,但可能占用端口资源(可通过调整SO_REUSEADDR优化)。
通过三次握手和四次挥手,TCP 实现了可靠、稳定的连接管理机制。