TCP协议中的三次握手与四次挥手
三次握手
图片来源:自己画的
三次握手(Three-Way Handshake)是 TCP/IP 协议中建立连接的过程,它用于确保通信双方都能准备好开始数据传输,并且能同步双方的初始序列号。三次握手是一个可靠的连接建立过程,目的是为了确保双方的连接状态一致,且数据传输能够顺利进行。
三次握手的步骤
三次握手的过程是通过三个数据包来完成的,它的步骤如下:
-
客户端 → 服务器:SYN(同步请求)
客户端首先向服务器发送一个 SYN(Synchronize)包,用来请求建立连接。这个包包含客户端的初始序列号(Seq
),即客户端从哪个序列号开始发送数据。此时,客户端处于 SYN_SEND 状态。发送的包格式:
- SYN = 1
- Seq = X(客户端的初始序列号)
-
服务器 → 客户端:SYN + ACK(同步应答)
服务器收到客户端的 SYN 包后,回复一个 SYN + ACK(同步应答)包,表示同意建立连接,并将自己的初始序列号Seq
设置为服务器选择的初始序列号(Y
)。同时,服务器会将客户端的序列号加 1 作为应答号(Ack = X + 1
),以告诉客户端它已经成功接收到客户端的请求。发送的包格式:
- SYN = 1
- ACK = 1
- Seq = Y(服务器的初始序列号)
- Ack = X + 1(确认客户端的序列号)
-
客户端 → 服务器:ACK(确认)
客户端收到服务器的 SYN + ACK 包后,会发送一个确认包 ACK,表示自己已经接收到服务器的应答,并且确认序列号为Y + 1
。此时,客户端和服务器之间的连接就正式建立起来了。发送的包格式:
- SYN = 0
- ACK = 1
- Seq = X + 1(客户端确认号)
- Ack = Y + 1(确认服务器的序列号)
三次握手的状态变化
-
客户端:
- CLOSED → SYN_SENT(发送 SYN 包)
- SYN_SENT → ESTABLISHED(接收到 ACK 包,连接建立成功)
-
服务器:
- CLOSED → LISTEN(等待客户端的连接请求)
- LISTEN → SYN_RECEIVED(接收到 SYN 包,发送 SYN + ACK 包)
- SYN_RECEIVED → ESTABLISHED(接收到客户端的 ACK 包,连接建立成功)
三次握手的作用
- 同步序列号:三次握手过程中,双方会交换初始的序列号,确保后续数据传输时双方的序列号是同步的。每次连接的建立都会选择新的序列号。
- 确认双方的接收能力:三次握手确保双方都可以接收数据,并且知道对方可以发送和接收数据。
- 建立连接时的确认机制:通过三次握手,双方可以确认对方的存在、连接能力以及对数据包的响应能力。
为什么是三次?
- 第一次握手:客户端发送一个 SYN 包,告知服务器自己希望建立连接,并同步初始序列号。
- 第二次握手:服务器收到客户端的 SYN 包后,发送一个 SYN + ACK 包,表示自己同意建立连接,并确认客户端的序列号。
- 第三次握手:客户端收到服务器的 SYN + ACK 包后,发送一个 ACK 包,表示确认接收到服务器的序列号和连接建立请求。
只有在这三次交换完成后,客户端和服务器才能正式开始数据通信。
三次握手与可靠性
三次握手的三个步骤,确保了以下几个方面的可靠性:
- 双方的确认:通过交换序列号和确认号,确保双方的初始连接序列号一致。
- 连接的双向确认:客户端和服务器都会明确地确认对方是否准备好建立连接。
- 防止旧连接干扰:由于每次建立连接都会选择新的序列号,这避免了过去的连接对新连接产生干扰。
三次握手与四次挥手的对比
- 三次握手用于连接的建立,确保通信双方准备好进行数据传输。
- 四次挥手用于连接的终止,确保双方都没有更多的数据需要发送,从而安全关闭连接。
举个简单例子
假设有一个客户端和服务器:
-
客户端 → 服务器:SYN
客户端想要与服务器建立连接,发送一个带有 SYN 标志的数据包,告诉服务器开始连接。
SYN = 1, Seq = X
-
服务器 → 客户端:SYN + ACK
服务器收到客户端的 SYN 包后,响应一个带有 SYN 和 ACK 标志的数据包,表示同意连接。服务器还会随机选择自己的初始序列号。
SYN = 1, ACK = 1, Seq = Y, Ack = X + 1
-
客户端 → 服务器:ACK
客户端收到服务器的 SYN + ACK 包后,向服务器发送一个带 ACK 标志的数据包,表示自己也收到了服务器的序列号,连接正式建立。
ACK = 1, Seq = X + 1, Ack = Y + 1
通过这三次数据包交换,客户端和服务器之间的连接正式建立,双方可以开始数据传输。
总结
三次握手是 TCP/IP 协议中用于建立连接的过程,确保了双方的通信双方的同步和确认。在这个过程中,客户端和服务器交换了初始序列号,确保了双方的连接状态一致,能够安全有效地开始数据传输。
四次挥手(Four-Way Handshake)是指在 TCP 协议中,关闭一个连接的过程。它是 TCP 连接终止的标准过程。四次挥手确保了双方都可以正常关闭连接,且数据传输的完整性得到保证。
在 TCP 协议中,数据传输是通过 三次握手(Three-Way Handshake)建立连接的,而断开连接则需要通过四次挥手。
四次挥手
图片来源:自己画的
四次挥手的过程
四次挥手的过程如下:
-
客户端发起连接终止(FIN):
- 客户端(主动关闭方)向服务器发送一个 FIN(Finish)报文段,表示客户端的数据已经发送完毕,希望关闭连接。
- 客户端进入 FIN_WAIT_1 状态,等待服务器的确认。
-
服务器确认客户端的请求(ACK):
- 服务器收到客户端的 FIN 请求后,发送一个 ACK 报文段作为确认,确认号是客户端的 SEQ + 1。
- 服务器进入 CLOSE_WAIT 状态。
-
服务器发送连接终止(FIN):
- 服务器发送一个 FIN 报文段,表示服务器也已经没有数据要发送了,准备关闭连接。
- 服务器进入 LAST_ACK 状态,等待客户端的确认。
-
客户端确认服务器的请求(ACK):
- 客户端收到服务器的 FIN 报文后,发送一个 ACK 报文段作为确认,确认号是服务器的 SEQ + 1。
- 客户端进入 TIME_WAIT 状态,等待可能存在的延迟的 ACK 报文段。
- 客户端等待一段时间(通常是 2MSL,最大报文段生存时间)以确保服务器收到了确认,然后进入 CLOSED 状态,连接完全关闭。
四次挥手过程的状态变化:
-
客户端状态:
FIN_WAIT_1
:等待服务器确认关闭连接。FIN_WAIT_2
:等待服务器发送关闭请求。TIME_WAIT
:等待可能延迟的包到达,确保服务器收到确认。CLOSED
:连接完全关闭。
-
服务器状态:
CLOSE_WAIT
:等待应用层关闭连接。LAST_ACK
:等待客户端确认关闭连接。CLOSED
:连接完全关闭。
为什么是四次?
四次挥手的原因是,在 TCP 协议中,连接是全双工的,即每一方向的数据传输是独立的。因此,客户端和服务器需要分别确认各自的数据已经发送完毕,才能安全地关闭连接。
- 第一步:客户端希望关闭连接,发送 FIN,表示客户端没有数据要发送了。
- 第二步:服务器收到 FIN 后,发送 ACK,表示确认客户端没有数据要发送了,但服务器可能仍然有数据要发送。
- 第三步:服务器发送 FIN,表示服务器也没有数据要发送了,准备关闭连接。
- 第四步:客户端收到服务器的 FIN 后,发送 ACK,确认连接的关闭。
四次挥手与三次握手的区别:
- 三次握手用于连接的建立,确保双方都准备好开始通信。
- 四次挥手用于连接的关闭,确保双方都能安全地关闭连接,防止数据丢失。
示例:
- 客户端 → 服务器:
FIN
- 服务器 → 客户端:
ACK
(确认收到FIN
) - 服务器 → 客户端:
FIN
- 客户端 → 服务器:
ACK
(确认收到服务器的FIN
)
在四次挥手完成后,TCP 连接会被完全关闭,双方的通信完全结束。
总结:
四次挥手是 TCP 连接断开的标准过程,通过这种方式,双方确保各自的所有数据都已经成功传输,并且在适当的时机安全地关闭连接。