TCP三次握手与四次挥手
字数 2791 2025-11-02 08:11:07

TCP三次握手与四次挥手

描述
TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。为了建立一条可靠的连接,TCP使用了“三次握手”机制;为了终止连接,则使用了“四次挥手”机制。这是网络编程和互联网基础中至关重要的核心知识点。

解题过程/知识点讲解

我们将分两步来理解这个过程:首先是三次握手建立连接,然后是四次挥手终止连接。

第一步:理解TCP三次握手(连接建立)

三次握手的目标是通信双方确认彼此的发送和接收能力正常,并同步初始序列号(Sequence Number, SYN)。

  1. 第一次握手(SYN)

    • 发起方(客户端) 想要与服务器建立连接。
    • 动作:客户端发送一个TCP数据包。这个数据包的特点是:
      • 其首部的SYN(同步)标志位被设置为1(即 SYN=1)。
      • 它会随机选择一个初始序列号(seq = x)。序列号是保证数据按顺序传输的关键。
    • 状态变化:发送后,客户端进入 SYN-SENT(同步已发送)状态。
    • 含义:这个包像是在说:“你好服务器,我想和你建立连接。我的初始序列号是x,你听到了吗?”
  2. 第二次握手(SYN-ACK)

    • 接收方(服务器) 收到了客户端的SYN包。
    • 动作:服务器如果同意建立连接,会回复一个数据包。这个数据包的特点是:
      • 首部SYN标志位和ACK(确认)标志位都设置为1(即 SYN=1, ACK=1)。
      • 它也会随机生成自己的初始序列号(seq = y)
      • 同时,它会对收到的客户端序列号进行确认,其确认号(Acknowledgment Number, ack)字段设置为 x + 1(即 ack = x + 1)。ack = x + 1 的意思是:“我确实收到了你发来的序列号为x的包,我期望你下一次从序列号x+1开始发送数据。”
    • 状态变化:发送后,服务器进入 SYN-RCVD(同步已收到)状态。
    • 含义:这个包像是在说:“我听到了你的请求(ack=x+1),我同意建立连接。我的初始序列号是y,你听到了吗?”
  3. 第三次握手(ACK)

    • 发起方(客户端) 收到了服务器的SYN-ACK包。
    • 动作:客户端需要再次发送一个确认包。这个数据包的特点是:
      • 首部ACK标志位设置为1(即 ACK=1)。
      • 序列号 seq = x + 1(因为第一次握手的SYN包消耗了一个序列号)。
      • 确认号 ack = y + 1,表示确认收到了服务器的SYN包。
    • 状态变化:发送后,客户端进入 ESTABLISHED(连接已建立)状态。服务器收到这个ACK包后,也进入 ESTABLISHED 状态。
    • 含义:这个包像是在说:“我也听到你的回复了,连接建立成功!”

为什么是三次,而不是两次?
关键在于防止“已失效的连接请求报文”突然传到服务器,导致服务器错误地打开连接。

  • 场景:客户端发送了一个连接请求(第一个SYN),但这个包在网络中滞留了。客户端超时未收到回复,于是重发了一个SYN并成功建立连接、传输数据、关闭连接。此时,那个滞留在网络中的第一个SYN包终于到达了服务器。
  • 如果是两次握手:服务器收到这个失效的SYN,会误以为客户端又发起了新连接,于是回复SYN-ACK(第二次握手)并直接进入 ESTABLISHED 状态,开始等待客户端发送数据,从而白白浪费了服务器资源。
  • 如果是三次握手:服务器回复SYN-ACK后,客户端会识别出这是一个失效的请求(因为它没有主动发起新连接),因此不会发送第三次的ACK确认。服务器由于收不到ACK,就不会建立连接,从而避免了资源浪费。

第二步:理解TCP四次挥手(连接终止)

四次挥手的目标是双方都确认要关闭连接。由于TCP连接是全双工的(数据可以双向流动),每个方向必须单独关闭。

  1. 第一次挥手(FIN)

    • 主动关闭方(假设是客户端) 的数据已发送完毕,请求关闭连接。
    • 动作:客户端发送一个数据包,其首部FIN(结束)标志位设置为1(FIN=1)。
    • 状态变化:发送后,客户端进入 FIN-WAIT-1(终止等待1)状态。
    • 含义:客户端对服务器说:“我这边没有数据要发送了,我想关闭我从你那里的数据通道(客户端到服务器的方向)。”
  2. 第二次挥手(ACK)

    • 被动关闭方(服务器) 收到了客户端的FIN包。
    • 动作:服务器发送一个确认包(ACK=1),其确认号 ack 为客户端序列号加1。
    • 状态变化:发送后,服务器进入 CLOSE-WAIT(关闭等待)状态。
    • 含义:服务器对客户端说:“哦,我知道你要关闭了。” 此时,TCP处于半关闭状态,即客户端到服务器的通道已关闭,客户端不能再发送数据,但服务器到客户端的通道仍然开放,服务器可能还有数据要发送给客户端。
    • 客户端状态变化:客户端收到这个ACK后,从 FIN-WAIT-1 进入 FIN-WAIT-2(终止等待2)状态,等待服务器发送FIN包。
  3. 第三次挥手(FIN)

    • 被动关闭方(服务器) 将剩余数据发送完毕后,也准备关闭连接。
    • 动作:服务器发送一个数据包,其首部FIN标志位设置为1(FIN=1)。
    • 状态变化:发送后,服务器进入 LAST-ACK(最后确认)状态。
    • 含义:服务器对客户端说:“我这边数据也发完了,我也要关闭了(服务器到客户端的通道)。”
  4. 第四次挥手(ACK)

    • 主动关闭方(客户端) 收到了服务器的FIN包。
    • 动作:客户端发送一个确认包(ACK=1),其确认号 ack 为服务器序列号加1。
    • 状态变化:发送后,客户端进入 TIME-WAIT(时间等待)状态。请注意,此时连接并未立即释放。客户端需要等待 2MSL(Maximum Segment Lifetime,最大报文段生存时间,通常为1-2分钟)的时间后,才进入 CLOSED 状态。
    • 服务器状态变化:服务器收到这个ACK后,立即进入 CLOSED 状态。

为什么客户端需要TIME-WAIT状态?等待2MSL是为了什么?
主要有两个原因:

  1. 可靠地终止连接:确保客户端发送的最后一个ACK能到达服务器。如果这个ACK在网络中丢失,服务器在 LAST-ACK 状态下会因为超时而重传它的FIN包。客户端在 TIME-WAIT 状态下收到重传的FIN后,会重发ACK并重新计时等待2MSL。
  2. 让旧连接的报文在网络中消逝:等待2MSL时间,足以让本次连接过程中产生的所有报文都在网络中“消逝”(超过最大生存时间被丢弃),这样再建立新连接时,就不会受到旧连接报文的干扰。

通过以上循序渐进的步骤,我们就完整地理解了TCP如何通过三次握手可靠地建立连接,以及通过四次挥手优雅地终止连接。

TCP三次握手与四次挥手 描述 TCP(传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议。为了建立一条可靠的连接,TCP使用了“三次握手”机制;为了终止连接,则使用了“四次挥手”机制。这是网络编程和互联网基础中至关重要的核心知识点。 解题过程/知识点讲解 我们将分两步来理解这个过程:首先是三次握手建立连接,然后是四次挥手终止连接。 第一步:理解TCP三次握手(连接建立) 三次握手的目标是通信双方确认彼此的发送和接收能力正常,并同步初始序列号(Sequence Number, SYN)。 第一次握手(SYN) : 发起方(客户端) 想要与服务器建立连接。 动作 :客户端发送一个TCP数据包。这个数据包的特点是: 其首部的 SYN(同步)标志位被设置为1 (即 SYN=1)。 它会随机选择一个 初始序列号(seq = x) 。序列号是保证数据按顺序传输的关键。 状态变化 :发送后,客户端进入 SYN-SENT (同步已发送)状态。 含义 :这个包像是在说:“你好服务器,我想和你建立连接。我的初始序列号是x,你听到了吗?” 第二次握手(SYN-ACK) : 接收方(服务器) 收到了客户端的SYN包。 动作 :服务器如果同意建立连接,会回复一个数据包。这个数据包的特点是: 首部 SYN标志位和ACK(确认)标志位都设置为1 (即 SYN=1, ACK=1)。 它也会随机生成自己的 初始序列号(seq = y) 。 同时,它会对收到的客户端序列号进行确认,其 确认号(Acknowledgment Number, ack)字段设置为 x + 1 (即 ack = x + 1)。 ack = x + 1 的意思是:“我确实收到了你发来的序列号为x的包,我期望你下一次从序列号x+1开始发送数据。” 状态变化 :发送后,服务器进入 SYN-RCVD (同步已收到)状态。 含义 :这个包像是在说:“我听到了你的请求(ack=x+1),我同意建立连接。我的初始序列号是y,你听到了吗?” 第三次握手(ACK) : 发起方(客户端) 收到了服务器的SYN-ACK包。 动作 :客户端需要再次发送一个确认包。这个数据包的特点是: 首部 ACK标志位设置为1 (即 ACK=1)。 其 序列号 seq = x + 1 (因为第一次握手的SYN包消耗了一个序列号)。 其 确认号 ack = y + 1 ,表示确认收到了服务器的SYN包。 状态变化 :发送后,客户端进入 ESTABLISHED (连接已建立)状态。服务器收到这个ACK包后,也进入 ESTABLISHED 状态。 含义 :这个包像是在说:“我也听到你的回复了,连接建立成功!” 为什么是三次,而不是两次? 关键在于防止“已失效的连接请求报文”突然传到服务器,导致服务器错误地打开连接。 场景 :客户端发送了一个连接请求(第一个SYN),但这个包在网络中滞留了。客户端超时未收到回复,于是重发了一个SYN并成功建立连接、传输数据、关闭连接。此时,那个滞留在网络中的第一个SYN包终于到达了服务器。 如果是两次握手 :服务器收到这个失效的SYN,会误以为客户端又发起了新连接,于是回复SYN-ACK(第二次握手)并直接进入 ESTABLISHED 状态,开始等待客户端发送数据,从而白白浪费了服务器资源。 如果是三次握手 :服务器回复SYN-ACK后,客户端会识别出这是一个失效的请求(因为它没有主动发起新连接),因此不会发送第三次的ACK确认。服务器由于收不到ACK,就不会建立连接,从而避免了资源浪费。 第二步:理解TCP四次挥手(连接终止) 四次挥手的目标是双方都确认要关闭连接。由于TCP连接是全双工的(数据可以双向流动),每个方向必须单独关闭。 第一次挥手(FIN) : 主动关闭方(假设是客户端) 的数据已发送完毕,请求关闭连接。 动作 :客户端发送一个数据包,其首部 FIN(结束)标志位设置为1 (FIN=1)。 状态变化 :发送后,客户端进入 FIN-WAIT-1 (终止等待1)状态。 含义 :客户端对服务器说:“我这边没有数据要发送了,我想关闭我从你那里的数据通道(客户端到服务器的方向)。” 第二次挥手(ACK) : 被动关闭方(服务器) 收到了客户端的FIN包。 动作 :服务器发送一个确认包(ACK=1),其确认号 ack 为客户端序列号加1。 状态变化 :发送后,服务器进入 CLOSE-WAIT (关闭等待)状态。 含义 :服务器对客户端说:“哦,我知道你要关闭了。” 此时,TCP处于 半关闭状态 ,即客户端到服务器的通道已关闭,客户端不能再发送数据,但服务器到客户端的通道仍然开放,服务器可能还有数据要发送给客户端。 客户端状态变化 :客户端收到这个ACK后,从 FIN-WAIT-1 进入 FIN-WAIT-2 (终止等待2)状态,等待服务器发送FIN包。 第三次挥手(FIN) : 被动关闭方(服务器) 将剩余数据发送完毕后,也准备关闭连接。 动作 :服务器发送一个数据包,其首部 FIN标志位设置为1 (FIN=1)。 状态变化 :发送后,服务器进入 LAST-ACK (最后确认)状态。 含义 :服务器对客户端说:“我这边数据也发完了,我也要关闭了(服务器到客户端的通道)。” 第四次挥手(ACK) : 主动关闭方(客户端) 收到了服务器的FIN包。 动作 :客户端发送一个确认包(ACK=1),其确认号 ack 为服务器序列号加1。 状态变化 :发送后,客户端进入 TIME-WAIT (时间等待)状态。请注意,此时连接并未立即释放。客户端需要等待 2MSL (Maximum Segment Lifetime,最大报文段生存时间,通常为1-2分钟)的时间后,才进入 CLOSED 状态。 服务器状态变化 :服务器收到这个ACK后,立即进入 CLOSED 状态。 为什么客户端需要TIME-WAIT状态?等待2MSL是为了什么? 主要有两个原因: 可靠地终止连接 :确保客户端发送的最后一个ACK能到达服务器。如果这个ACK在网络中丢失,服务器在 LAST-ACK 状态下会因为超时而重传它的FIN包。客户端在 TIME-WAIT 状态下收到重传的FIN后,会重发ACK并重新计时等待2MSL。 让旧连接的报文在网络中消逝 :等待2MSL时间,足以让本次连接过程中产生的所有报文都在网络中“消逝”(超过最大生存时间被丢弃),这样再建立新连接时,就不会受到旧连接报文的干扰。 通过以上循序渐进的步骤,我们就完整地理解了TCP如何通过三次握手可靠地建立连接,以及通过四次挥手优雅地终止连接。