返回

揭秘TCP序列号和确认号的变化规律,让你成为网络高手!

后端

TCP 序列号和确认号:洞悉网络通信的秘密武器

一、TCP 三次握手:序列号和确认号的初始约定

TCP 三次握手是建立可靠 TCP 连接的基石。在这个过程中,客户端和服务器交换序列号和确认号,确保数据传输的安全性。

  • 客户端首先发送一个 SYN(同步)报文,其中包含客户端的初始序列号 (ISN)。
  • 服务器收到 SYN 报文后,回复一个 SYN+ACK(同步确认)报文,包含服务器的 ISN 和对客户端 ISN 加 1 的确认号。
  • 客户端收到 SYN+ACK 报文后,发送一个 ACK(确认)报文,包含对服务器 ISN 加 1 的确认号和客户端的 ISN 加 1。

这样,双方就协商了初始序列号并建立了连接。

代码示例:

# 客户端发送 SYN 报文
client_socket.send(bytes("SYN", "utf-8"))

# 服务器接收 SYN 报文并发送 SYN+ACK 报文
server_socket.recv(1024)
server_socket.send(bytes("SYN+ACK", "utf-8"))

# 客户端接收 SYN+ACK 报文并发送 ACK 报文
client_socket.recv(1024)
client_socket.send(bytes("ACK", "utf-8"))

二、TCP 四次挥手:序列号和确认号的优雅告别

当连接不再需要时,TCP 使用四次挥手机制优雅地关闭连接。

  • 客户端发送一个 FIN(结束)报文,表示不再发送数据。
  • 服务器收到 FIN 报文后,发送一个 ACK 报文,确认 FIN 报文。
  • 服务器发送一个 FIN 报文,表示不再接收数据。
  • 客户端收到 FIN 报文后,发送一个 ACK 报文,确认 FIN 报文。

连接关闭后,双方释放资源。

代码示例:

# 客户端发送 FIN 报文
client_socket.send(bytes("FIN", "utf-8"))

# 服务器接收 FIN 报文并发送 ACK 报文
server_socket.recv(1024)
server_socket.send(bytes("ACK", "utf-8"))

# 服务器发送 FIN 报文
server_socket.send(bytes("FIN", "utf-8"))

# 客户端接收 FIN 报文并发送 ACK 报文
client_socket.recv(1024)
client_socket.send(bytes("ACK", "utf-8"))

三、TCP 数据传输:序列号和确认号的步步为营

在数据传输过程中,序列号和确认号发挥着至关重要的作用。

  • 发送方为每个数据包分配唯一的序列号,按顺序递增。
  • 接收方收到数据包后,检查序列号。如果正确,则存储数据并发送一个 ACK 报文,其中包含数据包序列号加 1 的确认号。
  • 发送方收到 ACK 报文后,将确认号与发送的数据包的序列号进行比较。如果相等,则表示数据包已成功传输;否则,表示数据包丢失,需要重传。

四、序列号和确认号的意义

序列号和确认号的变化规律确保了 TCP 连接的可靠性:

  • 序列号保证数据包按顺序传输。
  • 确认号确认接收方已正确收到数据包。
  • 重传机制处理丢失或损坏的数据包。

掌握这些规律对于理解和解决网络通信问题至关重要。

五、常见问题解答

1. 序列号和确认号是同一回事吗?

不,序列号标识发送的数据包,而确认号标识已成功接收的数据包。

2. 为什么需要序列号和确认号?

为了确保数据按顺序传输且完整无损。

3. 如果数据包丢失或损坏会怎样?

发送方会收到一个错误 ACK,然后重传丢失或损坏的数据包。

4. 为什么 TCP 握手需要三次?

三次握手允许客户端和服务器协商初始序列号并避免在连接建立之前就开始传输数据。

5. 为什么 TCP 挥手需要四次?

四次挥手确保双方都能优雅地关闭连接并释放资源。