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

TCP三次握手总结

1.概述

TCP是面向连接的可靠传输协议,在数据传输前,通信双方必须通过三次握手建立连接。其核心作用是同步序列号、协商参数(如MSS、窗口缩放因子),并确认双方具备收发能力

2.目的

  • 确保双方都能发送和接收数据(全双工通信)。

  • 交换初始序列号(ISN,Initial Sequence Number),为后续可靠传输(如确认、重传)奠定基础。

  • 协商可选参数(如最大报文段长度MSS、窗口缩放因子、选择性确认SACK等)。

3.详细过程

  • 服务器通过listen()进入LISTEN状态,等待连接。

  • 客户端通过connect()发起连接。

步骤

握手 方向 报文内容 发送后状态
第一次 客户端 → 服务器 SYN=1seq=x(x为随机数) 客户端:SYN-SENT
第二次 服务器 → 客户端 SYN=1ACK=1seq=y(y为随机数),ack=x+1 服务器:SYN-RCVD
第三次 客户端 → 服务器 ACK=1seq=x+1ack=y+1(可携带数据) 客户端:ESTABLISHED
服务器收到后:ESTABLISHED
sequenceDiagramparticipant C as 客户端participant S as 服务器Note over C: CLOSEDNote over S: LISTENC->>S: SYN (seq = x)Note over C: SYN-SENTS->>C: SYN-ACK (seq=y, ack=x+1)Note over S: SYN-RCVDC->>S: ACK (ack = y+1)Note over C: ESTABLISHEDNote over S: ESTABLISHED

4. 关键字段与标志位

  • SYN:同步序列号,在握手阶段用于建立连接,消耗一个序列号。
  • ACK:确认号有效,除第一次握手外,后续报文均需设置。
  • seq(序列号):本报文段数据的第一个字节的序号。初始值(ISN)为随机数。
  • ack(确认号):期望收到对方下一个报文段数据的第一个字节的序号,且表示之前序号的数据已成功接收。

5. 状态转换(简化)

  • 客户端CLOSEDSYN-SENTESTABLISHED
  • 服务器CLOSEDLISTENSYN-RCVDESTABLISHED

6. 为什么必须是三次握手?

两次握手的问题

如果只有两次握手,服务器在收到客户端的SYN后即进入ESTABLISHED,但此时客户端可能并未准备好(例如客户端发送的SYN因网络延迟重传,后来才到达服务器),导致服务器资源被浪费(建立无效连接)。

经典场景:客户端发送的第一个SYN在网络中滞留,超时重传后建立连接并关闭。滞留的SYN随后到达服务器,服务器误以为是新连接,回复SYN-ACK并进入ESTABLISHED,但客户端已关闭,导致服务器一直等待数据(半开连接),浪费资源。

四次握手的不足

四次握手理论上可行,但效率低。将第二次握手的SYN和ACK合并为一个报文,可以减少一次交互,提高建立速度。因此三次握手是最优解。

7. 常见问题与扩展

Q1:握手过程中丢包怎么办?

  • 第一次握手丢包:客户端超时重传SYN(重传次数可配置,通常为5次左右)。
  • 第二次握手丢包:客户端收不到SYN-ACK,会超时重传SYN;服务器已发送SYN-ACK,等待第三次ACK,若超时未收到,服务器重传SYN-ACK(次数有限)。
  • 第三次握手丢包:服务器收不到ACK,重传SYN-ACK;客户端收到重复的SYN-ACK后,会重新发送ACK(或忽略,视实现而定)。若重传多次仍无响应,服务器释放半连接资源。

Q2:初始序列号(ISN)为什么是随机的?

  • 防止旧连接的数据包被误认为是新连接的包(避免“历史连接干扰”)。
  • 提高安全性,避免攻击者猜测序列号进行会话劫持。

Q3:三次握手可以携带数据吗?

  • 前两次握手(SYN报文)不能携带数据,因为此时连接尚未建立,双方未准备好接收数据。
  • 第三次握手(ACK报文)可以携带数据。部分实现允许在第三次握手中捎带数据,以减少一次RTT(往返时间)。

Q4:SYN Flood攻击是什么?

攻击者伪造大量源IP,向服务器发送SYN,但不完成第三次握手,导致服务器维护大量半连接(占用内存),耗尽资源。防御手段包括:

  • SYN Cookie:服务器收到SYN后,不立即分配资源,而是根据连接信息计算一个Cookie作为初始序列号回复,若收到合法的ACK,再分配资源。
  • 增大半连接队列、缩短超时时间、使用防火墙过滤等。

Q5:同时打开(Simultaneous Open)如何处理?

双方同时向对方发送SYN,此时会进行四次交互(两个SYN和两个ACK),最终建立连接。这种情况较少见,但TCP规范支持。

8. 实际抓包示例

下面是用Wireshark捕获的一次HTTP访问过程中的TCP三次握手(客户端访问服务器80端口)。注意:Wireshark默认显示相对序列号(从0开始),实际原始序列号是随机值。

Pasted image 20260224222556

Pasted image 20260224223606
Pasted image 20260224223707
Pasted image 20260224223824

逐行解析

  1. 第1行(第一次握手):客户端(端口53354)向服务器(端口80)发送SYN报文。

    • Seq=0:相对序列号为0,表示这是本次连接的起始序列号(原始ISN为某个随机值)。

    • Win=65535:通知接收窗口大小为65535字节。

    • MSS=1460:通告本端支持的最大报文段长度为1460字节。

    • WS=256:窗口缩放因子为256,用于扩大窗口(实际窗口大小 = 窗口值 × 2^WS)。

    • SACK_PERM:支持选择性确认(SACK)选项。

  2. 第2行(第二次握手):服务器回复SYN-ACK报文。

    • Seq=1:服务器的相对序列号为1(原始序列号随机)。

    • Ack=1:确认号是1,表示期望收到客户端下一个序列号为1的字节(即确认了客户端的SYN)。

    • Win=64240MSS=1460SACK_PERMWS=128:服务器通告自己的参数。

  3. 第3行(第三次握手):客户端发送ACK报文。

    • Seq=1:客户端的下一个序列号(此时尚未发送数据)。

    • Ack=1:确认了服务器的SYN(期望收到服务器序列号为1的字节)。

    • Win=65280:更新窗口大小。

    • 此时连接建立,双方进入ESTABLISHED状态。

  4. 第4行:握手完成后,客户端立即发送HTTP GET请求(数据包长度为542字节),开始传输数据。

http://www.jsqmd.com/news/409343/

相关文章:

  • 随笔 6
  • 表格速查手册:Burp Suite 高频功能与快捷键(收藏级)
  • 题解:AcWing 891 Nim游戏
  • Django Cookie/Session
  • MCP文献综述:AI与外部世界的标准化交互桥梁
  • AngularJS Scope(作用域)
  • 科普文___三分钟带你看懂AI大模型(图文教程)
  • 实战排坑文:Burp Suite 抓包失败/无法抓HTTPS/爆破慢(问答式)
  • TF-IDF:从公式直觉到工程实现
  • 20260224_220210_非专业也能看懂的AI大模型工作原理!
  • 从DeepSeek到Seedance_2.0,国产大模型杀疯
  • C 标准库 - <string.h>
  • 题解:AcWing 890 能被整除的数
  • 大小端序存储
  • HyperRAG实战教程(非常详细),超图多跳推理从入门到精通,收藏这一篇就够了!
  • Tauri 中实现自更新(Auto Update)
  • 【DREAMVFIA开源】量子云平台构建:服务化量子计算资源管理
  • MCP Apps深度解读教程(非常详细),重构Web应用从入门到精通,收藏这一篇就够了!
  • 题解:AcWing 889 满足条件的01序列
  • .NET 11 预览版1:CoreCLR 在 WebAssembly 上的全面集成与性能突破
  • 题解:AcWing 888 求组合数 IV
  • 题解:AcWing 887 求组合数 III
  • Java 方法引用
  • Java基础(下)之Stream
  • Java基础(下)之方法引用
  • 题解:AcWing 886 求组合数 II
  • 题解:AcWing 885 求组合数 I
  • 功能炸裂!推荐一款低代码数据大屏可视化系统,内置丰富模版,支持拖拽构建炫酷大屏
  • 视频孪生终结者:镜像视界空间神经系统与空间控制权重构——融合统一空间坐标反演体系 × 三维实时定位引擎 × 多路径概率展开模型 × 前向围堵优化算法的跨行业空间压制与主动调度控制平台
  • 大数据领域数据产品的搜索功能优化