当前位置: 首页 > news >正文

TCP为什么采用三次握手而不是二次握手

TCP采用三次握手(Three-way Handshake)而不是二次握手,主要是为了解决网络中的延迟重复报文初始序列号同步问题,确保连接的可靠性和安全性。以下是具体原因:


1. 防止历史重复连接导致的资源浪费

  • 问题场景:如果客户端发送的第一次握手报文(SYN)因网络延迟滞留,客户端会重发一个新的SYN。若采用二次握手,服务端在收到滞留的旧SYN后会直接建立连接(发送SYN-ACK后认为连接已建立),但客户端会忽略这个响应(因为序列号不匹配),导致服务端长期等待,浪费资源。
  • 三次握手的解决:服务端在收到SYN后会等待客户端的第三次ACK确认(第三次握手),只有收到ACK后才真正建立连接。若ACK未到达,服务端会超时关闭连接,避免资源浪费。

场景1:旧SYN 早于 新SYN到达(常规情况)

  1. 客户端发送旧SYN(延迟滞留)

    • 客户端发送 SYN=1, seq=100(旧SYN),但该报文在网络中滞留,未到达服务端。
    • 客户端未收到 SYN-ACK,触发超时重传。
  2. 客户端发送新SYN(正常到达)

    • 客户端重传 SYN=1, seq=300(新SYN),新SYN先到达服务端
    • 服务端回复 SYN-ACK, seq=500, ack=301(确认客户端的 seq=300)。
    • 此时连接尚未建立!服务端处于 SYN_RCVD 状态,等待客户端的第三次 ACK
  3. 客户端回复第三次ACK

    • 客户端收到 SYN-ACK 后,发送 ACK=1, seq=301, ack=501(确认服务端的 seq=500)。
    • 至此,三次握手完成,连接正式建立(服务端进入 ESTABLISHED 状态)。
  4. 滞后的旧SYN到达服务端(关键区别)

    • 旧SYN SYN=1, seq=100 终于到达服务端。
    • 服务端误认为这是一个新连接,回复 SYN-ACK, seq=600, ack=101
    • 但客户端会忽略此 SYN-ACK(因为当前连接已建立,且 ack=101 不匹配客户端的序列号 seq=301)。
    • 服务端因收不到第三次 ACKack=601),会超时关闭这个半连接(避免资源浪费)。

如果是 二次握手 会怎样?

假设TCP采用二次握手(即服务端发送 SYN-ACK 后直接认为连接建立):

  1. 当旧SYN SYN=1, seq=100 到达服务端时:
    • 服务端回复 SYN-ACK, seq=600, ack=101,并立即认为连接已建立
    • 客户端因序列号不匹配(期望 ack=301),忽略此 SYN-ACK
    • 结果:服务端为旧SYN维护了一个无效连接,直到超时。

关键区别

步骤三次握手二次握手
服务端收到SYN后的行为发送 SYN-ACK,等待第三次 ACK 才建立连接。发送 SYN-ACK 后立即建立连接。
对延迟旧SYN的处理因无第三次 ACK,服务端会超时关闭无效连接。服务端会维持无效连接,直到超时(资源浪费)。
安全性防止历史SYN干扰,确保连接唯一性。可能因延迟SYN建立多余连接,易受攻击(如SYN洪泛)。

场景2:旧SYN 晚于 新SYN到达

  1. 客户端发送SYN=1, seq=100(旧SYN),延迟滞留。
  2. 客户端重传SYN=1, seq=300(新SYN),新SYN先到达服务端
    • 服务端回复SYN-ACK, seq=500, ack=301,连接正常建立(三次握手完成)。
  3. 延迟的旧SYN到达服务端
    • 服务端误认为是新连接,回复SYN-ACK, seq=600, ack=101
    • 客户端发现ack=101不匹配(当前序列号已是301),忽略该SYN-ACK。
    • 如果是二次握手:服务端会为旧SYN建立另一个无效连接。
    • 三次握手解决:服务端因收不到ACK(ack=601),不会建立连接。

关键结论

  1. 无论旧SYN早到还是晚到,二次握手都会导致服务端可能建立无效连接。
    • 旧SYN早到:客户端不认可,服务端空等。
    • 旧SYN晚到:服务端多建一个无用连接。
  2. 三次握手的核心作用
    • 通过第三次ACK确认双方序列号,过滤所有延迟或重复的SYN
    • 服务端仅在收到ACK后才会真正分配资源,避免资源浪费。

现实类比

假设你两次通知同事开会:

  1. 第一次通知(旧):“周一开会”(延迟未送达)。
  2. 第二次通知(新):“周二开会”(同事收到并回复“收到”)。
    • 如果旧通知后来到达
      • 二次握手:同事看到“周一开会”直接准备会议室(浪费资源)。
      • 三次握手:同事会等你确认“周一开会”的回复(但你不会回复,因为已改时间),同事放弃准备。

为什么不能依赖“新SYN一定先到”?

网络延迟是不可控的,可能因路由变化、拥塞、重传等导致报文乱序。TCP的设计必须假设最坏情况(即旧报文可能在任何时候到达),而三次握手是解决这一问题的最小成本方案。


三次握手 vs 二次握手 的核心差异

对比项三次握手二次握手
服务端何时认为连接建立?收到客户端的 第三次 ACK 后才建立发送 SYN-ACK立即认为连接已建立
无效连接的处理服务端在 SYN_RCVD 状态等待 ACK未建立完整连接,超时关闭(资源占用较少)服务端 已认为连接建立ESTABLISHED),但客户端不认可,导致 完全无效的连接 占用资源
资源占用情况仅维护 半连接队列(SYN队列),占用较少维护 全连接队列,占用更多资源(如 socket、内存等)
受攻击风险(如SYN洪泛)更容易防御(未完成握手的连接可快速清理)更危险(攻击者伪造SYN可快速耗尽服务端连接资源)

为什么说“三次握手更优”?

虽然最终都会超时关闭,但 三次握手 在以下方面更优:

  1. 资源占用更少

    • 三次握手下,服务端在收到 SYN 后仅进入 SYN_RCVD 状态(半连接),占用资源较少。
    • 二次握手下,服务端直接进入 ESTABLISHED 状态,分配完整连接资源(如 socket、缓冲区等),即使客户端不认可,这些资源也会被占用直到超时。
  2. 防止SYN洪泛攻击

    • 攻击者可以伪造大量 SYN 报文,消耗服务端资源。
    • 三次握手:服务端仅维护半连接队列,超时时间较短(如Linux默认 SYN_TIMEOUT=60s),能更快清理无效请求。
    • 二次握手:服务端会为每个 SYN 分配完整连接资源,更容易被攻击打满。
  3. 避免“滞留旧SYN”建立无效连接

    • 即使旧 SYN 晚到,三次握手下服务端仍会因收不到 ACK 而关闭,不会建立实际可用的无效连接
    • 二次握手下,服务端会为旧 SYN 分配资源,尽管客户端不认可,但仍可能影响服务端性能(如占用端口、内存等)。

举例说明

假设服务端最大连接数为 1000:

  • 三次握手:攻击者发送 1000 个 SYN,服务端仅维护 1000 个半连接(SYN_RCVD),不会影响已建立的正常连接。
  • 二次握手:攻击者发送 1000 个 SYN,服务端直接建立 1000 个无效的 ESTABLISHED 连接,导致正常用户无法访问。

结论

虽然最终都会超时关闭,但 三次握手资源占用、安全性、抗攻击能力 上明显优于二次握手。
核心区别:三次握手下,服务端在收到 ACK不会分配完整连接资源,而二次握手会过早分配,导致更高的风险。


总结

  • 三次握手的必要性:通过第三次 ACK 确认双方的初始序列号,并过滤延迟或重复的 SYN
  • 二次握手的问题:服务端无法区分有效连接和延迟的旧SYN,会导致资源浪费。
  • 你的质疑是正确的:在之前的描述中,“连接建立”的说法不严谨,必须明确第三次 ACK 的作用。

2. 同步双方的初始序列号(ISN)

  • TCP需要通过序列号保证数据有序性和可靠性。三次握手确保双方双向序列号的同步
    1. 客户端发送SYN(携带自己的ISN)。
    2. 服务端回复SYN-ACK(携带自己的ISN并确认客户端的ISN)。
    3. 客户端发送ACK(确认服务端的ISN)。
  • 二次握手的缺陷:若只有两次握手,服务端无法确认客户端是否收到了自己的ISN(即客户端可能未准备好接收数据)。

3. 避免恶意攻击(如SYN洪泛)

  • 二次握手会让服务端在发送SYN-ACK后立即建立连接,攻击者可以伪造大量SYN报文耗尽服务端资源(SYN Flood攻击)。
  • 三次握手的缓解:服务端在收到第三次ACK前仅维护半连接状态(如SYN队列),未完成的连接会被超时清除,降低资源占用。

4. 双向信道可靠性确认

  • TCP是全双工协议,需要确保双向通信的可靠性。三次握手明确双方均具备收发能力:
    1. 客户端→服务端:SYN证明客户端发送正常。
    2. 服务端→客户端:SYN-ACK证明服务端收发正常。
    3. 客户端→服务端:ACK证明客户端接收正常。

二次握手的问题总结

如果仅用两次握手:

  • 服务端无法区分滞留的旧SYN报文正常新连接
  • 服务端无法确认客户端是否收到了自己的SYN-ACK,可能导致单向连接(客户端未准备好接收数据)。
  • 更易受到资源耗尽攻击。

类比现实场景

想象两人通话:

  1. A:“你能听到我吗?”(SYN)
  2. B:“我能听到你,你能听到我吗?”(SYN-ACK)
  3. A:“我也能听到你!”(ACK)
    此时双方才确认通信正常。若只有前两步,A无法确认B是否听到了自己的第二次回应。

总结:三次握手是平衡可靠性和效率的最小次数,既避免了历史报文干扰,又确保了双向通信的初始序列号同步,同时增强了抗攻击能力。

http://www.dtcms.com/a/314139.html

相关文章:

  • 使用 Marian 进行机器翻译详解及对应案例
  • 在安卓中使用 FFmpegKit 剪切视频并添加文字水印
  • Android进程基础:Zygote
  • (JAVA)自建应用调用企业微信API接口,设置企业可信IP
  • 开疆智能ModbusTCP转Profient网关连接ER机器人配置案例
  • DPDK中的TCP头部处理
  • 第五篇: 深入解析基于 SQLAlchemy 的聊天记录持久化模块:`message_model` 与数据库操作封装
  • 高速信号设计之 PCIe6.0 篇
  • Windows中Idea或者其他开发工具如何使用Google Sans Code - 码农开源等宽字体
  • 数据结构:如何判断一个链表中是否存在环(Check for LOOP in Linked List)
  • JSqlParser学习笔记 快速使用JSqlParser
  • 从exec到Shell:深度解析Linux进程等待,程序替换与自主Shell实现
  • 电脑一键重装系统win7/win10/win11无需U盘(无任何捆绑软件图文教程)
  • OBS 基础 21 充满某个源的策略
  • Android GPU测试
  • 电子电气架构 ---智能电动汽车嵌入式软件开发过程中的block点
  • 【Linux指南】软件安装全解析:从源码到包管理器的进阶之路
  • 移动端生产网页设计误区:工业级操作场景下的手势交互创新
  • 【Django】-3- 处理HTTP响应
  • AUTOSAR CP:深度揭秘APPL层(Application Layer)!SWC分配策略与端口交互的终极指南
  • IntelliJIDEA上传GitHub全攻略
  • 国产智能三防手机哪款最好?这款支持单北斗、5G-A、IP68
  • 进一步分析云手机的优势有哪些?
  • chatgpt plus简单得,不需要求人,不需要野卡,不需要合租,不需要昂贵的价格
  • 手机防沉迷新招:安卓手机如何成为管理iPhone的遥控器?
  • Redis 实现互斥锁解决Redis击穿
  • Realme手机怎样相互远程控制?Realme可以被其他手机远程控制吗?
  • GPTs——定制的小型智能体
  • 微算法科技(NASDAQ: MLGO)开发量子边缘检测算法,为实时图像处理与边缘智能设备提供了新的解决方案
  • vue3+天地图。添加标注和点击当前去掉其他的标注