卡码笔记
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
首页
计算机基础
C++
Java
面经
笔记广场 (opens new window)
代码随想录 (opens new window)
  • 操作系统

  • 网络

    • 基础概念

    • TCP 深入

      • TCP三次握手的详细流程及核心目的?
      • 三次握手的过程?以及为什么是三次而不是四次和两次
        • 简要回答
        • 详细回答
        • 知识图解
        • 知识拓展
      • 四次挥手的过程是怎样的?为什么是四次而不是三次或五次?
      • TIME_WAIT状态的作用?
      • TCP连接如何确保可靠性?
      • 能说说拥塞控制是怎样实现的吗?
      • TCPKeepalive和HTTPKeep-Alive的区别?
    • HTTP 进阶

    • 安全与缓存

    • 综合应用

  • 数据库

# 三次握手的过程?以及为什么是三次而不是四次和两次

# 简要回答

  1. TCP的三次握手:(首先服务器要进入 LISTEN 状态,等待客户端的连接。)
    • 第一次握手:
      客户端随机生成初始序列号(如x),发送SYN = 1的连接请求报文段,并进入 SYN-SENT 状态,等待服务器确认。
    • 第二次握手:
      服务器在收到来自客户端发来的SYN报文后,随机生成自己的序列号(如y),并发送SYN = 1, ACK = 1的确认报文段,确认号为x + 1,之后服务器进入 SYN-RCVD 状态。
    • 第三次握手:
      客户端收到服务器发来的确认报文段后,再向服务器发送ACK = 1的确认报文段,确认号为y + 1;客户端发送完该报文段后,进入 ESTABLISHED 状态。当服务器接收到该报文段后,也进入 ESTABLISHED 状态,此时TCP连接建立成功。
  2. 为什么是三次握手而不是两次或四次?
    • 第三次握手的必要性:
      防止已经失效的重复连接请求(例如网络延迟的冗余SYN报文)导致服务器误开无效连接。
    • 为什么不能是两次握手:
      两次握手无法防止历史SYN报文干扰,可能导致服务器资源浪费。
    • 为什么不是四次握手:
      三次握手已经能确保双方收发能力可靠,四次握手会增加额外延迟且无必要。

# 详细回答

  1. TCP的三次握手:(首先服务器要进入 LISTEN 状态,等待客户端的连接。)
    • 第一次握手(SYN):
      Δ 客户端向服务器发送一个连接请求报文段,其中同步位SYN = 1 ,初始序号seq通常随机设置,记为x。
      Δ 该请求报文不携带任何数据,即报文段的数据部分为空,但是仍然需要消耗掉一个序号(下次发送的报文的seq从x + 1开始)。
      Δ SYN报文发送后,客户端进入 SYN-SENT 状态。
    • 第二次握手(SYN-ACK):
      Δ 服务器收到客户端发来的连接请求后,如果同意建立连接,则向客户端发送一个确认报文段,其中同步位SYN = 1,确认位ACK = 1 。因为TCP提供全双工通信,服务器也可以向客户端发送数据,所以服务器也需要为自己随机设置一个初始序号seq,不妨记为y,而确认号ack = x + 1(表示来自客户端的编号在x之前的所有字节都已正确接收,现在服务器希望得到编号为x + 1的字节)。
      Δ 和第一次握手的请求报文段类似,第二次握手的确认报文段不携带任何数据,即报文段的数据部分为空,但是仍然需要消耗掉一个序号。(下次发送的报文的seq从y + 1开始)
      Δ SYN-ACK报文发送后,服务器进入 SYN-RCVD 状态。
    • 第三次握手(ACK):
      Δ 客户端收到服务器发来的确认报文段后,需要再向服务器发送确认报文段,其中确认位ACK = 1 ,序号seq = x + 1,确认号ack = y + 1(因为第二次握手时服务器的确认报文段占用了一个序号)。
      Δ 第三次握手的确认报文段可以携带数据,也可以不携带数据。如果不携带数据,则不消耗序号(即TCP连接建立后,客户端发送的下一个请求报文的序号seq仍然为x + 1)。
      Δ 客户端发送完ACK报文后,进入 ESTABLISHED 状态;当服务器接收到该报文段后,也进入 ESTABLISHED 状态;此时TCP连接建立成功,双方可以进行数据传输。
  2. 为什么是三次握手而不是两次或四次?
    • 第三次握手的必要性:
      第三次握手可以防止已经失效的连接请求报文段突然又到达了TCP服务器端,而造成的服务器资源浪费。考虑这样一个场景:假如客户端发送的已经失效的SYN(因网络延迟)请求报文到达服务器,服务器会回复SYN-ACK确认报文。若只有两次握手,客户端会忽略此响应,但服务器认为连接已经成功建立,就会持续等待客户端发来数据,导致“半开连接”,浪费大量服务器资源。如果进行了第三次握手,服务器在发送确认报文段后还需要客户端进行确认,如果客户端未在时间限制内确认,服务器可以认为连接未建立成功,就不会继续占用资源。
    • 为什么不能是两次握手:
      ① 两次握手时,服务器无法区分当前连接是否是延迟的旧请求。客户端可能已放弃连接,但服务器仍在等待数据,造成资源浪费。
      ② RFC 793(TCP协议标准文档)明确要求三次握手:只有三次交互能保证双方初始序列号(ISN)同步。
    • 为什么不是四次握手:
      三次握手已经能确保双方收发能力可靠,四次握手会增加额外延迟且无必要。

# 知识图解

  1. TCP三次握手的示意图如下:
    image
  2. TCP四次挥手的示意图如下:
    image

# 知识拓展

  1. 为什么是三次握手(详细版本):
    第三次握手可以防止已经失效的连接请求报文段(例如由于网络拥塞而超时的SYN报文)突然又到达了TCP服务器端,而造成的服务器资源浪费。假设 TCP 仅需两次握手即可建立连接,考虑如下场景——
    ① 客户端发送SYN报文,但由于网络拥塞,该报文滞留在了某个节点,导致服务器未能正确接收。
    ② 客户端在指定时间内没有收到来自服务器的SYN-ACK报文,触发超时重传机制,客户端因此重新发送了一个SYN报文给服务器。
    ③ 服务器成功收到了重传的SYN报文,并且此后的第二次握手正常进行,TCP连接成功建立;客户端和服务器通信结束后,TCP连接被释放。
    ④ 但是,此前由于网络拥塞而滞留的SYN报文在延误了一段时间后,达到了服务器端并被服务器正确接收。
    ⑤ 服务器认为客户端要建立新的连接,于是向客户端发送SYN-ACK报文。由于当前情景假设了TCP仅需两次握手即可建立连接,所以此时在服务器看来,TCP连接已经成功建立,服务器接下来会持续等待客户端发来数据。
    ⑥ 客户端收到服务器发来的SYN-ACK报文后,由于自己并没有主动发出连接请求,所以直接丢弃该确认报文。而服务器那边会一直等待客户端发送数据,这就造成大量服务器资源浪费。
    如果进行了第三次握手,服务器在发送SYN-ACK报文后还需要客户端进行确认,如果客户端没有在限定时间内确认,服务器可以认为连接建立失败,就不会再继续占用资源了。
  2. 保活计时器:
    因为TCP提供了全双工通信,所以在TCP连接建立后,客户端和服务器都可以随时向对方发送数据。为了避免服务器无效等待客户端(比如客户端故障),服务器每次收到来自客户端的数据后,都会重置保活计时器并计时。假如保活计时器计时期间,服务器始终未收到来自客户端的数据,那么当保活计时器即使周期结束之后,服务器就会每隔一定时间(75s)向客户端发送一次探测报文段。若连续发送 10个 探测报文段后,服务器还没有收到客户端的响应,则服务器端认为该客户端已经失去联系,就会关闭相关的TCP连接。
Last Updated: 3/10/2026, 6:08:48 PM

← TCP三次握手的详细流程及核心目的? 四次挥手的过程是怎样的?为什么是四次而不是三次或五次? →

评论

验证登录状态...

侧边栏
夜间
卡码简历
代码随想录
卡码投递表🔥
2026群
添加客服微信 PS:通过微信后,请发送姓名-学校-年级-2026实习/校招
支持卡码笔记
鼓励/支持/赞赏Carl
1. 如果感觉本站对你很有帮助,也可以请Carl喝杯奶茶,金额大小不重要,心意已经收下
2. 希望大家都能梦想成真,有好的前程,加油💪