TCP 三次握手和四次挥手
TCP 是面向连接的传输层协议。通信双方在传输应用数据前,需要通过三次握手建立连接;数据传输结束后,通常通过四个报文段释放双向连接。
TCP 首部中的相关字段

序列号 seq
序列号字段占 32 位。TCP 会对字节流中的数据进行编号,报文段中的序列号通常表示该报文段所携带数据的第一个字节编号。
建立连接时,通信双方会分别选择初始序列号。SYN 和 FIN 即使不携带应用数据,也各自会消耗一个序列号。
确认号 ack
确认号字段占 32 位,表示接收方期望收到的下一个字节序号。
例如,若已经正确收到对方序号为 100 到 199 的数据,则确认号通常为 200。
ACK 标志位
ACK 占 1 位。当 ACK 为 1 时,确认号字段有效。连接建立后,绝大多数 TCP 报文段都会设置该标志位。
需要区分:
- 小写的
ack通常表示确认号字段的值。 - 大写的
ACK表示 TCP 首部中的确认标志位。
SYN 标志位
SYN 用于建立连接并同步双方的初始序列号。
SYN=1、ACK=0:通常表示连接请求。SYN=1、ACK=1:通常表示同意建立连接并确认对方的请求。
FIN 标志位
FIN 表示发送方已经没有数据需要发送,请求关闭当前方向上的连接。TCP 是全双工协议,因此一个方向关闭后,另一个方向仍然可以继续传输数据。
三次握手

假设客户端的初始序列号为 x,服务器的初始序列号为 y。
第一次握手:客户端发送 SYN
客户端向服务器发送连接请求:
SYN=1, seq=x
发送后,客户端从 CLOSED 进入 SYN-SENT 状态。
第二次握手:服务器发送 SYN+ACK
服务器收到客户端的请求后,确认客户端的序列号,并发送自己的初始序列号:
SYN=1, ACK=1, seq=y, ack=x+1
发送后,服务器从 LISTEN 进入 SYN-RECEIVED 状态。
第三次握手:客户端发送 ACK
客户端收到服务器的响应后,再发送确认报文:
ACK=1, seq=x+1, ack=y+1
服务器收到该确认后,双方进入 ESTABLISHED 状态,可以传输应用数据。
第三次握手中的纯 ACK 报文如果不携带数据,本身不会额外消耗序列号。
为什么需要三次握手
三次握手主要完成以下工作:
- 确认双方的发送能力和接收能力基本正常。
- 同步双方各自的初始序列号。
- 避免失效的旧连接请求直接导致服务器建立错误连接。
- 协商 TCP 选项,例如最大报文段长度和窗口扩大因子。
只进行两次交互时,服务器无法确认客户端是否已经收到服务器的初始序列号和连接确认,因此需要第三次确认。
四次挥手

下面以客户端主动关闭连接为例。假设客户端发送 FIN 时的序列号为 u,服务器当前序列号为 v。
第一次挥手:客户端发送 FIN
客户端表示自己已经没有数据需要发送:
FIN=1, ACK=1, seq=u
客户端进入 FIN-WAIT-1 状态。FIN 会消耗一个序列号。
第二次挥手:服务器确认客户端的 FIN
服务器收到 FIN 后发送确认:
ACK=1, seq=v, ack=u+1
服务器进入 CLOSE-WAIT 状态,客户端收到确认后进入 FIN-WAIT-2 状态。
此时客户端到服务器方向已经关闭,但服务器到客户端方向仍可继续传输尚未发送完的数据,这种状态称为半关闭。
第三次挥手:服务器发送 FIN
服务器完成剩余数据发送后,请求关闭自己的发送方向。假设此时服务器序列号为 w:
FIN=1, ACK=1, seq=w, ack=u+1
服务器进入 LAST-ACK 状态,等待客户端的最终确认。
第四次挥手:客户端确认服务器的 FIN
客户端收到服务器的 FIN 后发送确认:
ACK=1, seq=u+1, ack=w+1
客户端进入 TIME-WAIT 状态。服务器收到该确认后进入 CLOSED 状态。
为什么通常需要四次挥手
TCP 的两个传输方向需要分别关闭。主动关闭方发送 FIN 后,被动关闭方可能仍有数据需要发送,因此通常先单独确认对方的 FIN,等剩余数据发送完毕后再发送自己的 FIN。
如果被动关闭方收到 FIN 时已经没有数据需要发送,也可能把 ACK 与自己的 FIN 合并到同一个报文段中。此时网络上看到的报文段数量可能少于四个,但连接释放的逻辑仍然包含两个方向的关闭与确认。
TIME-WAIT 状态
主动关闭方通常会在 TIME-WAIT 状态等待 2MSL。MSL 表示报文段在网络中的最大生存时间。
等待的主要原因有两个:
- 若最后一个
ACK丢失,被动关闭方会重发FIN,主动关闭方仍能再次确认。 - 让当前连接产生的延迟报文在网络中消失,避免影响之后使用相同四元组建立的新连接。
TIME-WAIT 是 TCP 保证可靠关闭的重要机制,并不等同于程序异常。
常见状态汇总
| 状态 | 含义 |
|---|---|
LISTEN | 服务器监听连接请求 |
SYN-SENT | 客户端已发送连接请求 |
SYN-RECEIVED | 服务器已收到请求并等待最终确认 |
ESTABLISHED | 连接已建立 |
FIN-WAIT-1 | 主动关闭方已发送 FIN,等待确认 |
FIN-WAIT-2 | 主动关闭方已收到确认,等待对方的 FIN |
CLOSE-WAIT | 被动关闭方已确认对方的 FIN,等待应用关闭连接 |
LAST-ACK | 被动关闭方已发送自己的 FIN,等待最终确认 |
TIME-WAIT | 主动关闭方等待 2MSL |
CLOSED | 连接已关闭 |
喜欢的话,留下你的评论吧~