三次握手
TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手来进行的。三次握手的过程如下图:
- 一开始,客户端和服务端都处于
CLOSE
状态。先是服务端主动监听某个端口,处于LISTEN
状态
- 客户端会随机初始化序号(
client_isn
),将此序号置于 TCP 首部的「序号」字段中,同时把SYN
标志位置为1
,表示SYN
报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于SYN-SENT
状态。
- 服务端收到客户端的
SYN
报文后,首先服务端也随机初始化自己的序号(server_isn
),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入client_isn + 1
, 接着把SYN
和ACK
标志位置为1
。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于SYN-RCVD
状态。
- 客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部
ACK
标志位置为1
,其次「确认应答号」字段填入server_isn + 1
,最后把报文发送给服务端,这次报文可以携带客户到服务端的数据,之后客户端处于ESTABLISHED
状态。 - 服务端收到客户端的应答报文后,也进入
ESTABLISHED
状态。
我理解的过程:
确认序(ack)列号的含义:
- 确认收到对方的报文
- 期望下一次对方的序列号为我的确认序列号(比如说这次我(服务端)给客户端发过去7,客户端回给我的序号就是7.)
确认序列号等于对方发送过来的序列号+标志位长度SYN(1)+数据长度
seq(序列号)
ack 确认序列号
第一次握手:客户端SYN置成1 ACK还是0 设序列号seq = X ack = 0
第二次握手:服务端SYN置成1 ACK还是1 seq = y ack = x + 1 + 0(数据没有)
第三次握手:客户端SYN置成0 ACK还是1 seq = x +1 +0 ack = y+1