TCP三次握手四次挥手详解与相关面试题

一、TCP 三次握手(Three-Way Handshake)

目的: 建立可靠的全双工通信通道,确保客户端与服务端都能正常发送和接收数据。

1.1 三次握手过程
  1. 第一次握手(SYN):

    • 客户端向服务端发送一个 SYN(Synchronize Sequence Number,同步序列号)报文,请求建立连接。
    • 标志位:SYN=1,序列号 Seq=x
    • 此时,客户端进入 SYN-SENT 状态。
  2. 第二次握手(SYN + ACK):

    • 服务端收到 SYN 后,确认客户端请求有效,回复 SYN 和 ACK(Acknowledgment,确认)报文。
    • 标志位:SYN=1, ACK=1,序列号 Seq=y,确认号 Ack=x+1(表示已收到客户端的 SYN)。
    • 服务端进入 SYN-RECEIVED 状态。
  3. 第三次握手(ACK):

    • 客户端收到服务端的 SYN + ACK 后,发送 ACK 报文确认。
    • 标志位:ACK=1,序列号 Seq=x+1,确认号 Ack=y+1(表示已收到服务端的 SYN)。
    • 客户端进入 ESTABLISHED(连接已建立) 状态,服务端接收 ACK 后也进入 ESTABLISHED 状态。

总结:

  • 通过三次握手,双方都确认了对方的接收和发送能力,确保通信链路的可靠性。

二、TCP 四次挥手(Four-Way Handshake)

目的: 优雅地关闭连接,确保双方的数据传输完成且不丢失。

2.1 四次挥手过程
  1. 第一次挥手(FIN):

    • 客户端发送 FIN(Finish)报文,表示不再发送数据,但仍可接收数据。
    • 标志位:FIN=1, Seq=u
    • 客户端进入 FIN-WAIT-1 状态。
  2. 第二次挥手(ACK):

    • 服务端收到 FIN 后,发送 ACK 确认报文,表示已收到客户端的请求。
    • 标志位:ACK=1, Seq=v, Ack=u+1
    • 服务端进入 CLOSE-WAIT 状态,客户端进入 FIN-WAIT-2 状态。
  3. 第三次挥手(FIN):

    • 当服务端发送完所有数据后,发送 FIN 报文,请求关闭连接。
    • 标志位:FIN=1, Seq=w
    • 服务端进入 LAST-ACK 状态。
  4. 第四次挥手(ACK):

    • 客户端收到 FIN 后,发送 ACK 确认报文,表示已收到关闭请求。
    • 标志位:ACK=1, Seq=u+1, Ack=w+1
    • 客户端进入 TIME-WAIT 状态,等待 2MSL(Maximum Segment Lifetime,最大报文段生存时间),以保证服务端收到 ACK 后可安全关闭。
    • 服务端收到 ACK 后立即进入 CLOSED 状态。
    • 2MSL 计时结束后,客户端也进入 CLOSED 状态。

总结:

  • 四次挥手中,FIN 和 ACK 是分开的,确保双方的数据能安全传输完毕。
  • 客户端的 TIME-WAIT 状态是为了保证最后的 ACK 能被服务端收到,避免半关闭连接问题。

三、为什么需要三次握手和四次挥手?

  • 三次握手: 防止历史连接请求干扰当前连接(SYN 失效问题)。
  • 四次挥手: 保证双方数据传输完成且无遗漏(全双工关闭)。

1. 为什么要三次握手?第 2 次握手传回了 ACK,为什么还要传回 SYN?

原因:防止历史连接请求干扰,确保双向通信能力。

  • 第一次握手(SYN): 客户端发送 SYN,表示自己能发送数据,想与服务端建立连接。
  • 第二次握手(SYN + ACK):
    • 服务端发送 ACK,确认收到客户端的 SYN。
    • 同时发送 SYN,表示自己也能发送数据,要求客户端确认。
  • 第三次握手(ACK): 客户端发送 ACK,确认收到服务端的 SYN,表示自己能接收数据。

如果第二次握手不发送 SYN,可能出现的问题:

  • 仅靠第二次握手的 ACK,客户端只知道服务端收到了 SYN,但不知道服务端的接收能力(能否接收客户端的数据)。
  • 服务端通过发送 SYN,确保客户端知道它能接收数据。

总结: 三次握手保证了双方的 发送能力接收能力 都确认无误,避免了历史失效连接请求干扰。


2. 为什么要四次挥手?为什么不能把服务器发送的 ACK 和 FIN 合并起来,变成三次挥手?

原因:TCP 是全双工协议,发送和接收通道独立关闭。

  • 四次挥手分开 ACK 和 FIN 的原因:
    • ACK 用于确认接收 之前对方的 FIN,表示“我知道你要断开发送通道了”。
    • FIN 用于请求关闭发送通道,表示“我也不再发送数据了”。

如果合并 ACK 和 FIN:

  • 问题: 服务端还可能有未发送的数据,此时直接发送 FIN 会导致数据丢失。
  • 四次挥手的好处:
    • 服务端可以在发送 ACK 后继续传输数据,直到发送完成后才发送 FIN,确保数据完整传输。

总结: 四次挥手确保双方都能完整地发送和接收数据,不会因为未发送完数据就断开连接。


3. 如果第二次挥手时服务器的 ACK 没有送达客户端,会怎样?

情况分析:服务端的 ACK 丢失,客户端一直处于 FIN-WAIT-1 状态。

处理机制:超时重传机制

  • 客户端未收到 ACK:
    • 会重新发送 FIN,直到收到 ACK 或超时重试次数用尽(通常是 TCP 重传机制控制)。
  • 服务端收到重传的 FIN:
    • 重新发送 ACK 确认,流程继续。
  • 如果多次重传未收到 ACK:
    • 客户端放弃连接关闭,可能触发错误处理或资源释放。

总结: 通过超时重传机制,TCP 能确保连接关闭的可靠性。


4. 为什么第四次挥手客户端需要等待 2 * MSL(报文段最长寿命)时间后才进入 CLOSED 状态?

原因:确保最后一个 ACK 报文可靠送达,防止旧连接影响新连接。

4.1 等待 2 * MSL 的作用
  1. 确保 ACK 被服务端收到:

    • 如果服务端未收到 ACK,会重新发送 FIN,客户端在 TIME-WAIT 状态下可以重新发送 ACK。
    • 这样可以保证服务端成功进入 CLOSED 状态,避免半关闭问题。
  2. 防止旧报文影响新连接:

    • 若不等待 2 * MSL,旧连接的延迟报文可能误入新连接,导致数据错乱。
    • 2 * MSL 确保旧连接的报文完全消失在网络中,避免干扰。

总结:

  • 第一个 MSL: 保证 ACK 的可靠送达。
  • 第二个 MSL: 确保旧报文不会干扰新连接。

总的来说,四次挥手和 2 * MSL 的设计都是为了保证 TCP 连接的可靠性和数据的完整性。

你可能感兴趣的:(网络,网络协议,tcp/ip)