TCP
在TCP中,数据被分割成多个数据包,并在发送端和接收端之间进行可靠传输。
三次握手
这是建立TCP连接的过程。在客户端和服务器之间,需要交换三个数据包以确认双方的连接参数并完成连接建立。
| A连接 | A标志位 | 序号 | B标志位 | B连接 |
---|
1 | CLOSED | | | | LISTEN |
1 | SYN_SEND | SYN=1 | Seq=x | -> | |
2 | | <- | Seq=y ACKN=x+1 | ACK=1 SYN=1 | SYN_RECV |
3 | ESTABLISHED | ACK=1 | Seq=x+1 ACKN=y+1 | -> | ESTABLISHED |
- 第一次握手:A端(客户端)发送连接请求报文段。
- 将
SYN
置为1,序号(Sequence Number)为x, - A端进入
SYN_SEND
状态,等待B端(服务端)确认。
- 第二次握手:B端 接收到A端发送的
SYN
报文段,现在需要对其确认。
- 设置 确认序列(Acknowledge Number)为序号加1,
ACK
置为1, - 同时发送
SYN
请求信息,序号为y, - 最后将两者放入同一报文段中,一并发给A端,
- B端进入
SYN_RECV
状态,等待A端确认。
- 第三次握手:A端接收到B端的
ACK+SYN
报文。
- 设置序号为x+1(报文的确认序号),
- 同时设置当前确认序号为y+1(报文序号+1),置
ACK
为1。 - 报文发送完毕后,A端与B端都将进入
ESTABLISHED
状态,完成三次握手。
四次挥手
这是终止TCP连接的过程。在数据传输结束后,需要交换四个数据包以确认连接的关闭。在某些情况下(如连接异常或服务器强制断开),则会同时置RST标志为1
| A连接 | A标志位 | 序号 | B标志位 | B连接 |
---|
1 | ESTABLISHED | | | | ESTABLISHED |
1 | FIN_WAIT_1 | FIN=1 | Seq=u | -> | CLOSE_WAIT |
2 | FIN_WAIT_2 | <- | Seq=v ACKN=u+1 | ACK=1 | |
3 | | <- | Seq=w ACKN=u+1 | ACK=1 FIN=1 | LAST_ACT |
4 | TIME_WAIT | ACK=1 | Seq=u+1 ACKN=w+1 | -> | CLOSED |
4 | CLOSED | 2MSL | | | |
- 第一次挥手:A端(即可能是客户端,也可能是服务端)发送结束连接报文段。(表示A端没有数据要发送给B端了)
- 置
FIN
为1,序号为u, - 发送后进入A端进入
FIN_WAIT_1
状态。
- 第二次挥手:B端接收到A端的结束连接报文,现需要对其确认。(即同意A端的关闭请求)
- 置
ACK
为1,确认序号为u加1, - 设置序号为v。
- 发送完成后B端进入
CLOSE_WAIT
状态,A端进入FIN_WAIT_2
状态。
- 第三次挥手:(如B端发送完成所有数据或也没有数据要发送给A端后)B端发送结束确认报文。
- 置
FIN
为1,序号为w。 - 同时置
ACK
为1,确认序号为u+1。 - B端进入
LAST_ACT
状态。
- 第四次挥手:A端接收到B端的结束确认报文,最后再对其确认。
- 设置序号为u+1(结束报文的确认序号),
- 同时置
ACK
为1,确认序号为w+1。 - 发送完成后A端进入
TIME_WAIT
状态,而B端接收完则进入CLOSED
状态。 - A端会等待
2MSL
,如没有新的报文(即证明B端已正常关闭),则A端进入CLOSED
状态。
思考
为什么TCP是三次握手,而挥手是四次呢?
这主要是因为三次握手是建立连接的过程,需要双方明确彼此的参数和状态;而四次挥手是关闭连接的过程,需要双方都明确彼此的关闭意图并完成资源的释放。这个过程中涉及到的一些数据包可能会因为网络延迟等原因需要多次尝试才能成功发送或接收,因此需要更多的数据包交换来确保连接的建立和关闭。