核心概念与背景
在开始之前,先明确几个关键点:
- TCP 是什么:传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议。
- '连接'是什么:TCP 的连接并非物理上的电路,而是通信双方在内存中维护的一种状态信息(如序列号、窗口大小等)。建立连接就是同步双方的初始状态。
- 标志位:TCP 头部中有几个重要的控制位,在握手挥手中起到关键作用:
- SYN:同步序列号,用于建立连接。
- ACK:确认,表示确认号字段有效。
- FIN:终止,用于关闭连接。
- 序列号与确认号:
- 序列号:标识发送的数据字节流的顺序。
- 确认号:期望收到对方下一个报文段的第一个数据字节的序列号,表示此序号之前的数据已成功接收。
三次握手 — 建立连接
三次握手的根本目的是:同步双方的初始序列号,并交换其他参数,为可靠数据传输做准备。同时,它也证明了双方都具有发送和接收的能力。
假设客户端(Client)主动发起连接,服务器(Server)等待连接。
第一步:第一次握手(Client -> Server)
- 客户端发送一个 TCP 报文段。
- 设置标志位 SYN = 1,表示这是连接请求。
- 同时,客户端会随机生成一个初始序列号
client_isn,放在序列号字段中。 - 此时不携带应用层数据。
- 客户端状态:从
CLOSED进入SYN-SENT(同步已发送)。
第二步:第二次握手(Server -> Client)
- 服务器收到 SYN 报文后,如果同意建立连接,则会回复一个报文段。
- 设置标志位 SYN = 1 和 ACK = 1。
- 服务器也会随机生成自己的初始序列号
server_isn,放在序列号字段中。 - 确认号字段设置为
client_isn + 1,表示'我已收到你的序列号为client_isn的 SYN 包,期待下一个数据从client_isn + 1开始'。 - 此时可以携带或不携带应用层数据(但通常不携带)。
- 服务器状态:从
LISTEN进入SYN-RCVD(同步已收到)。
第三步:第三次握手(Client -> Server)
- 客户端收到服务器的 SYN-ACK 报文后,会再发送一个确认报文。
- 设置标志位 ACK = 1。
- 序列号字段设置为
client_isn + 1(因为第一次握手消耗了一个序列号)。 - 确认号字段设置为
server_isn + 1,表示'我已收到你的序列号为server_isn的 SYN 包'。 - 此报文可以携带应用层数据(连接建立后即可开始传输)。
- 客户端状态:从
SYN-SENT进入ESTABLISHED(已建立连接)。 - 服务器收到这个 ACK 后,状态也从
SYN-RCVD进入ESTABLISHED。
为什么是三次,而不是两次?


