文章目录
隐藏
TCP(Transmission Control Protocol)是一个面向连接的、可靠的传输协议。TCP 的连接建立和断开过程中分别使用三次握手(Three-Way Handshake)和四次挥手(Four-Way Handshake)机制来确保数据传输的可靠性和一致性。下面将详细讲解这两个过程。
一、TCP 三次握手
三次握手是指在建立 TCP 连接时,客户端和服务端通过三个消息包的交互来确认双方的连接状态,保证通信的可靠性。
三次握手的过程:
- 第一次握手(SYN = 1,seq = x):客户端发送连接请求
- 客户端(Client)发送一个 SYN(Synchronize Sequence Number,同步序列号)请求报文给服务端(Server)。这是表示客户端请求与服务端建立连接。
- 同时,客户端选择一个初始序列号
seq = x
,表示从 x 开始传输数据。 - 此时,客户端进入 SYN_SENT 状态,等待服务端的响应。
- 第二次握手(SYN = 1,ACK = 1,seq = y,ack = x + 1):服务端确认收到请求
- 服务端收到客户端的 SYN 报文后,回应一个 ACK(Acknowledgment,确认)报文。这个报文包含两个重要信息:
- ACK = 1,ack =
x + 1
:表示确认收到了客户端的 SYN 报文,并告知客户端下一个希望接收到的数据序列号是x + 1
。 - SYN = 1,seq = y:服务端选择自己的初始序列号
y
,表示从 y 开始传输数据。
- ACK = 1,ack =
- 服务端进入 SYN_RECEIVED 状态,等待客户端的确认。
- 服务端收到客户端的 SYN 报文后,回应一个 ACK(Acknowledgment,确认)报文。这个报文包含两个重要信息:
- 第三次握手(ACK = 1,seq = x + 1,ack = y + 1):客户端确认建立连接
- 客户端收到服务端的 SYN + ACK 报文后,发送一个确认(ACK)报文给服务端:
- ACK = 1,ack =
y + 1
:表示确认收到了服务端的 SYN 报文,期待下一个收到的数据序列号是y + 1
。 - seq =
x + 1
:客户端继续以自己的序列号发送确认消息。
- ACK = 1,ack =
- 此时,客户端进入 ESTABLISHED 状态,表示连接已建立。
- 服务端收到这个报文后,也进入 ESTABLISHED 状态,双方可以开始正式的数据传输。
- 客户端收到服务端的 SYN + ACK 报文后,发送一个确认(ACK)报文给服务端:
为什么需要三次握手?
- 保证连接的可靠性:三次握手的目的是为了让双方都确认自己和对方的发送和接收能力正常。第一次握手客户端确认能发送消息,第二次握手服务端确认接收和发送能力正常,第三次握手客户端确认自己接收能力正常。
- 防止已失效的请求连接重新到达:如果只进行两次握手,某个旧的连接请求报文可能在网络中延迟到达,导致服务端错误地认为需要重新建立连接。三次握手能够有效地避免这种问题。
二、TCP 四次挥手
四次挥手是指在断开 TCP 连接时,客户端和服务端通过四个消息包的交互来确保双方都能安全地关闭连接。
四次挥手的过程:
- 第一次挥手(FIN = 1,seq = u):客户端请求断开连接
- 客户端发送一个 FIN(Finish)报文给服务端,表示它已经没有数据要发送了,准备关闭连接。
- 这个报文中包含:
- FIN = 1:表示断开连接的请求。
- seq =
u
:表示当前的序列号。
- 客户端进入 FIN_WAIT_1 状态,等待服务端的确认。
- 第二次挥手(ACK = 1,ack = u + 1):服务端确认断开请求
- 服务端收到客户端的 FIN 报文后,发送一个确认(ACK)报文给客户端,表示它收到了客户端的断开请求,并且同意关闭连接,但可能还有数据要传输。
- 报文中包含:
- ACK = 1,ack =
u + 1
:确认收到客户端的 FIN 报文。
- ACK = 1,ack =
- 这时,客户端进入 FIN_WAIT_2 状态,等待服务端的 FIN 报文。
- 服务端进入 CLOSE_WAIT 状态,等待自己所有数据传输完毕。
- 第三次挥手(FIN = 1,seq = v):服务端请求关闭连接
- 服务端发送 FIN 报文给客户端,表示它也没有数据要发送了,准备关闭连接。
- 报文中包含:
- FIN = 1:请求断开连接。
- seq =
v
:表示当前的序列号。
- 服务端进入 LAST_ACK 状态,等待客户端的最后确认。
- 第四次挥手(ACK = 1,ack = v + 1):客户端确认断开
- 客户端收到服务端的 FIN 报文后,发送一个确认(ACK)报文给服务端,表示确认断开连接。
- 报文中包含:
- ACK = 1,ack =
v + 1
:确认收到服务端的 FIN 报文。
- ACK = 1,ack =
- 客户端进入 TIME_WAIT 状态,等待一段时间(通常为 2*MSL,最大报文段生存时间)以确保服务端收到它的确认报文后再关闭连接。
- 服务端收到这个 ACK 报文后立即进入 CLOSED 状态,关闭连接。
- 客户端在等待 2*MSL 后,也进入 CLOSED 状态,正式关闭连接。
为什么需要四次挥手?
- 全双工关闭:TCP 连接是全双工的,意味着通信双方都能同时发送和接收数据。在关闭连接时,双方需要分别关闭各自的发送通道,因此需要四次挥手。
- 确保数据完整传输:在第二次挥手之后,服务端可能仍在发送数据,因此客户端需要等到服务端所有数据传输完毕并发出 FIN 请求后再关闭连接。
为什么客户端在第四次挥手后还需要等待 2*MSL?
客户端在进入 TIME_WAIT
状态时,会等待 2*MSL 的时间,这是为了确保:
- 确保服务端收到 ACK 报文:如果服务端没有收到客户端的 ACK 报文,它会重新发送 FIN 报文,客户端在
TIME_WAIT
状态下可以接收并重新发送 ACK 确认。 - 清理网络中的旧报文:等待 2*MSL 可以确保网络中与此连接相关的报文都已经消失,防止影响新的连接。
三、总结
TCP 三次握手:
- 客户端和服务端通过三次消息交互来建立连接,确保双方的发送和接收能力正常,并避免旧连接请求对当前连接的影响。
- 第一次握手:客户端发送 SYN 报文请求建立连接。
- 第二次握手:服务端确认请求,并发送 SYN+ACK 报文。
- 第三次握手:客户端确认建立连接,发送 ACK 报文。
TCP 四次挥手:
- 连接断开时,双方需要通过四次消息交互来安全地关闭连接,确保数据的完整传输。
- 第一次挥手:客户端发送 FIN 报文,表示没有数据要发送了。
- 第二次挥手:服务端发送 ACK 报文,确认收到 FIN 请求。
- 第三次挥手:服务端发送 FIN 报文,表示数据传输完毕。
- 第四次挥手:客户端发送 ACK 报文,确认断开连接,并等待一段时间再关闭。
这两个机制确保了 TCP 连接的可靠性和数据传输的完整性,是互联网通信的关键。
4o
You said:
FIN \ACK\SYN报文的区别?seq\ack 区别是什么
ChatGPT said:
ChatGPT
在 TCP 协议中,FIN
、ACK
、SYN
都是控制位(Control Flags),它们出现在 TCP 报文头部,用来指示连接的建立、确认或终止等行为。
1. FIN
、ACK
、SYN
报文的区别
1.1 SYN
(Synchronize)报文
- 用途:
SYN
位用于 同步序列号,主要在 TCP 连接建立 时使用。 - 作用:在 TCP 三次握手的过程中,
SYN
表示发起一个连接请求。- 当客户端向服务端发送
SYN
报文时,它携带了初始的序列号(seq
),表明客户端希望与服务端建立连接。 - 服务端通过回复带有
SYN
和ACK
的报文来确认它接收到了连接请求,并同步双方的序列号。
- 当客户端向服务端发送
1.2 ACK
(Acknowledgment)报文
- 用途:
ACK
位用于 确认,表示当前报文是在对之前接收到的数据包进行确认。 - 作用:几乎所有的 TCP 报文中都包含
ACK
位,用来确认接收到的数据。- 通过
ACK
,接收方告诉发送方它期望的下一个字节序列号是什么(即ack
字段)。 - 在三次握手的第二和第三步,
ACK
用于确认 SYN 报文。 - 在数据传输过程中,
ACK
也用于确认收到的有效数据。 - 断开连接的过程中,
ACK
用来确认FIN
报文的接收。
- 通过
1.3 FIN
(Finish)报文
- 用途:
FIN
位用于 关闭连接,表示发送方已经没有数据要发送了,想要关闭连接。 - 作用:
FIN
用于 TCP 四次挥手,发起一个连接的关闭请求。- 当一方想要终止连接时,会发送一个带有
FIN
标志的报文,表示它完成了数据的发送,并希望关闭连接。 - 另一方收到
FIN
后,需要回复一个ACK
报文进行确认,然后再决定是否发送自己的FIN
报文关闭整个连接。
- 当一方想要终止连接时,会发送一个带有
2. seq
和 ack
的区别
seq
(Sequence Number)和 ack
(Acknowledgment Number)是 TCP 报文头中的两个关键字段,分别用于跟踪数据的发送和接收。
2.1 seq
(序列号)
- 用途:
seq
字段表示 发送方 在 TCP 连接中的当前 数据包序列号,用于标识数据包的顺序。 - 作用:TCP 是一个基于字节流的协议,每个字节都有一个序列号。在每次发送数据时,发送方会在
seq
字段中填入当前数据包的序列号,表示数据从哪个字节开始。- 例如,客户端第一次发送数据时,
seq
字段可能为 100,表示这是数据流中的第 100 个字节。 - 接收方通过
ack
字段确认收到了这个序列号及之后的数据。
- 例如,客户端第一次发送数据时,
2.2 ack
(确认号)
- 用途:
ack
字段表示 接收方 希望从发送方接收的 下一个数据字节的序列号,用于确认已经成功接收的数据。 - 作用:当接收方收到数据包后,会回复一个带有
ACK
标志的报文,其中的ack
字段表示它期望接收的下一个字节序列号。- 例如,接收方收到序列号为 100 的数据后,回复的
ack
字段值为 101,表示它期待下一个数据包的起始序列号是 101。 - 如果发送方收到这个
ack
值,则知道之前发送的所有数据已经被成功接收。
- 例如,接收方收到序列号为 100 的数据后,回复的
区别总结:
seq
:表示发送方发出的数据的序列号,标识数据流中当前数据包的位置。ack
:表示接收方期望接收到的下一个字节的序列号,用于确认发送方发送的数据。
3. 应用场景总结
SYN
:用于建立连接,在 TCP 三次握手的第一步和第二步中使用。它帮助双方同步序列号并开始通信。ACK
:用于确认数据接收,出现在三次握手的第二步和第三步、数据传输期间的每次通信中,以及四次挥手期间。几乎每个报文都带有ACK
。FIN
:用于关闭连接,在 TCP 四次挥手中使用,表示发送方不再发送数据,准备关闭连接。seq
:跟踪发送方发送的数据流序列,用于确保数据包按顺序到达。ack
:跟踪接收方确认的字节序列号,用于通知发送方哪些数据已经被成功接收。
通过 SYN
建立连接,通过 FIN
断开连接,而 ACK
则用于在整个过程中确认数据的传输。 seq
和 ack
帮助 TCP 实现可靠、有序的数据传输。