TCP三次握手

三次握手

第一次握手(SYN

  • 客户端(Client)向服务器(Server)发起连接请求。

  • 客户端随机初始化一个序列号(client_isn),并将 SYN 标志位置为1,表示是一个 SYN 报文。

  • 发送 SYN 报文后,客户端进入 SYN-SENT 状态。

第二次握手(SYN+ACK

  • 服务器收到客户端的 SYN 报文后,随机初始化自己的序列号(server_isn)。

  • 服务器发送 SYN+ACK 报文:

    • SYN 标志位置为1,表示服务器同意建立连接。

    • ACK 标志位置为1,表示对客户端的 SYN 报文进行确认。

    • 确认应答号 字段填入 client_isn + 1

  • 发送 SYN+ACK 报文后,服务器进入 SYN-RCVD 状态。

第三次握手(ACK

  • 客户端收到 SYN+ACK 报文后,发送 ACK 报文:

    • ACK 标志位置为1,表示确认收到服务器的 SYN

    • 确认应答号 字段填入 server_isn + 1

    • 此报文可以携带应用层数据,也可以不携带。

  • 发送 ACK 报文后,客户端进入 ESTABLISHED 状态。

连接建立

  • 服务器收到 ACK 报文后,进入 ESTABLISHED 状态,至此,TCP 连接正式建立,客户端和服务器可以开始数据通信。

为什么是三次握手?不是一次、两次、四次?

首先,一次是不可能的,因为TCP要双方建立连接,所以肯定至少要一问一答来保证双方是正常能通讯的,不然就变UDP了。

然后,三次已经能建立稳定连接了,所以四次会多余一次开销,没必要,接下来只需要说明为什么两次不行即可

  • 三次握手才可以阻止重复历史连接的初始化

  • 三次握手才可以同步双方的初始序列号

  • 三次握手才让双方确认对方的接收发信息的能力

避免历史连接:

防止旧的重复连接初始化造成混乱

  1. 我们考虑一个场景,客户端先发送了 SYN(seq = 90)报文,然后客户端宕机了,而且这个 SYN 报文还被网络阻塞了,服务端并没有收到,接着客户端重启后,又重新向服务端建立连接,发送了 SYN(seq = 100)报文。

  2. 一个「旧 SYN 报文」比「最新的 SYN」 报文早到达了服务端,那么此时服务端就会回一个 SYN + ACK 报文给客户端,此报文中的确认号是 91(90+1)。

  3. 客户端收到后,发现自己期望收到的确认号应该是 100 + 1,而不是 90 + 1,于是就会回 RST 报文。

  4. 服务端收到 RST 报文后,就会释放连接。

  5. 后续最新的 SYN 抵达了服务端后,客户端与服务端就可以正常的完成三次握手了。

posted @ 2025-03-15 13:36  Zero&&One  阅读(168)  评论(0)    收藏  举报