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

网络通信基石:TCP三次握手的完整剖析

网络通信基石:TCP三次握手的完整剖析

    • 前言
    • 一、什么是三次握手?
    • 二、三次握手的完整流程图
    • 三、每一步的详细拆解
      • 第一步:客户端发送 SYN
      • 第二步:服务器回应 SYN + ACK
      • 第三步:客户端发送 ACK
    • 四、为什么不能两次握手?为什么不是四次?
      • 4.1 为什么不能两次握手?
      • 4.2 为什么不是四次握手?
    • 五、状态流转详解
    • 六、序列号(seq)和确认号(ack)的作用
      • 6.1 为什么需要随机初始序列号(ISN)?
      • 6.2 序列号如何增长?
    • 七、实战:用 Wireshark 抓包看三次握手
      • 7.1 抓包命令
      • 7.2 抓包结果解读
    • 八、常见面试题
      • Q1:什么是半连接队列和全连接队列?
      • Q2:SYN Flood 如何防御?
      • Q3:第三次握手可以携带数据吗?
      • Q4:如果第三次握手丢包了怎么办?
      • Q5:SYN 超时时间是多少?
    • 九、与其他协议对比
    • 十、总结速查表

🌺The Begin🌺点点关注,收藏不迷路🌺

⬇ ⬇ 底部 ⬇ ⬇

前言

TCP(Transmission Control Protocol,传输控制协议)是互联网最核心的协议之一。我们每天上网浏览网页、刷视频、发微信,背后都离不开 TCP 提供的可靠连接

而 TCP 建立连接的过程,有一个经典的名字——三次握手(Three-Way Handshake)

无论是后端开发、面试八股文,还是网络排错,三次握手都是绕不开的知识点。

今天这篇文章,我们从为什么需要三次握手 → 每一步详解 → 状态流转 → 常见问题,彻底讲透 TCP 三次握手。


一、什么是三次握手?

三次握手是 TCP 协议在传输数据之前,客户端和服务器之间建立连接的一个过程。

它的核心目的只有三个:

目的说明
确认双方收发能力正常确保双方都能正常发送和接收数据
同步初始序列号(ISN)为后续可靠传输打下基础
协商参数如窗口大小、MSS 等

为什么叫“握手”?因为双方需要互相确认,就像见面先打招呼。


二、三次握手的完整流程图

Client (客户端) Server (服务端) │ │ │ 1. SYN (seq=x) │ │ ─────────────────────────────► │ │ │ │ 2. SYN + ACK (seq=y, ack=x+1)│ │ ◄───────────────────────────── │ │ │ │ 3. ACK (seq=x+1, ack=y+1) │ │ ─────────────────────────────► │ │ │ │ 连接建立,开始传输数据 │

三、每一步的详细拆解

第一步:客户端发送 SYN

报文内容:

  • SYN = 1(同步位,表示请求建立连接)
  • seq = x(客户端随机生成的初始序列号,记为x
  • ACK = 0(此时还没收到确认)

发生时机:客户端调用connect()

此时状态:客户端 →SYN_SENT

核心作用:

  • 客户端告诉服务器:“我想跟你建立连接,我的初始序列号是x

第二步:服务器回应 SYN + ACK

报文内容:

  • SYN = 1(服务器也同意建立连接)
  • ACK = 1(确认收到客户端的 SYN)
  • seq = y(服务器随机生成的初始序列号,记为y
  • ack = x + 1(确认号 = 客户端的 seq + 1)

此时状态:服务器 →SYN_RCVD

核心作用:

  • 服务器告诉客户端:“我收到了你的请求,我也同意建立连接,我的初始序列号是y,请你确认。”

注意ack = x + 1意味着客户端下次发送数据时序列号应为x + 1


第三步:客户端发送 ACK

报文内容:

  • ACK = 1(确认位)
  • seq = x + 1(客户端的下一个序列号)
  • ack = y + 1(确认号 = 服务器的 seq + 1)

此时状态:客户端 →ESTABLISHED

服务器收到这个 ACK 后,也会进入ESTABLISHED状态。

核心作用:

  • 客户端告诉服务器:“我收到了你的确认,连接正式建立。”

四、为什么不能两次握手?为什么不是四次?

4.1 为什么不能两次握手?

假设只有两次握手:

Client ── SYN(x) ──► Server Client ◄── SYN(y)+ACK(x+1) ── Server

问题场景:旧连接的延迟 SYN 包

时间线: 1. 客户端发送 SYN(x)(旧连接,已超时关闭) 2. 服务器收到 SYN(x),回复 SYN(y)+ACK(x+1),进入 ESTABLISHED 3. 客户端认为这是旧连接的包,直接丢弃,不回复 ACK 4. 服务器一直等数据,浪费资源(半开连接)

结论:两次握手无法区分“新连接请求”和“旧连接的延迟包”。第三次 ACK 确保客户端确实在等待这个连接。

4.2 为什么不是四次握手?

三次已经足够:

  • 第一次:客户端告诉服务器“我要连接”
  • 第二次:服务器回应“收到,我也要连接”
  • 第三次:客户端确认“收到你的确认”

四次握手会有一次冗余确认,浪费一个报文。


五、状态流转详解

CLOSED CLOSED │ │ │ (客户端主动) │ (服务端被动) ▼ │ SYN_SENT │ │ │ │ 收到 SYN+ACK │ │ │ │ │ ▼ │ │ ESTABLISHED │ │ │ │ ▼ │ LISTEN (监听) │ │ │ SYN │ │ ────────────────────► │ │ ▼ │ SYN_RCVD │ │ │ SYN+ACK │ │ ◄──────────────────── │ │ │ │ ACK │ │ ────────────────────► ▼ │ ESTABLISHED ▼ 双方都进入 ESTABLISHED
状态含义
CLOSED关闭状态,没有连接
LISTEN服务器监听中,等待连接
SYN_SENT客户端已发送 SYN,等待 SYN+ACK
SYN_RCVD服务器收到 SYN,已回复 SYN+ACK,等待 ACK
ESTABLISHED连接已建立,可以传输数据

六、序列号(seq)和确认号(ack)的作用

6.1 为什么需要随机初始序列号(ISN)?

  • 安全性:防止被猜中序列号,避免 TCP 会话劫持攻击
  • 区分不同连接:同一对 IP 和端口的连接,通过序列号区分
  • 处理旧包:序列号可以识别并丢弃网络中延迟的旧数据包

6.2 序列号如何增长?

seq(x) → seq(x+1) seq(y) → seq(y+1) ack(x+1) → 表示期望下次收到 seq = x+1 的数据

举个例子:

客户端发送:seq=1000,数据长度=100字节 服务器回复:ack=1100(意味着已收到 100~1099,期望下一个是 1100)

七、实战:用 Wireshark 抓包看三次握手

7.1 抓包命令

# 抓取 HTTP 请求的 TCP 包tcpdump-ieth0host192.168.1.100 and port80-whandshake.pcap

7.2 抓包结果解读

1 0.000000 192.168.1.100 → 93.184.216.34 TCP 74 [SYN] Seq=0 Win=65535 2 0.023456 93.184.216.34 → 192.168.1.100 TCP 74 [SYN, ACK] Seq=0 Ack=1 Win=29200 3 0.023478 192.168.1.100 → 93.184.216.34 TCP 66 [ACK] Seq=1 Ack=1 Win=65535

可以看到:

  • 第 1 包:SYN,seq=0(相对值)
  • 第 2 包:SYN+ACK,seq=0,ack=1
  • 第 3 包:ACK,seq=1,ack=1

注意:Wireshark 默认显示相对序列号(相对于初始值),实际绝对值很大。


八、常见面试题

Q1:什么是半连接队列和全连接队列?

队列位置状态作用
半连接队列(SYN Queue)服务器SYN_RCVD存放收到 SYN 但未完成握手的连接
全连接队列(Accept Queue)服务器ESTABLISHED存放已完成握手等待应用层 accept 的连接

SYN Flood 攻击:客户端大量发送 SYN 但不回复 ACK,塞满半连接队列。

Q2:SYN Flood 如何防御?

  • SYN Cookie:不分配半连接,用加密 cookie 代替
  • 增大半连接队列net.ipv4.tcp_max_syn_backlog
  • 启用 SYN Proxy(如阿里云 Anti-DDoS)

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

可以。如果第三次 ACK 携带数据,服务器收到后既完成握手又把数据交给应用层。这称为TCP Fast Open(TFO)

Q4:如果第三次握手丢包了怎么办?

  • 客户端:发送完 ACK 后直接进入ESTABLISHED,开始发数据
  • 服务器:未收到 ACK,仍在SYN_RCVD,收不到客户端数据时会重传 SYN+ACK
  • 重传次数:默认 5 次,约 1 秒后超时断开

Q5:SYN 超时时间是多少?

Linux 默认初始重传超时(RTO)为1 秒,后续翻倍:1s、2s、4s、8s、16s,共31 秒后放弃。


九、与其他协议对比

协议连接方式握手次数是否可靠
TCP面向连接3 次(建立)/ 4 次(断开)
UDP无连接0 次
HTTP/1.1基于 TCP3 次(连接复用)
QUIC基于 UDP0-RTT 或 1-RTT是(应用层实现)

十、总结速查表

角色发送内容状态变化
客户端SYN(seq=x)CLOSED → SYN_SENT
服务器SYN+ACK(seq=y, ack=x+1)LISTEN → SYN_RCVD
客户端ACK(seq=x+1, ack=y+1)SYN_SENT → ESTABLISHED
服务器(收到 ACK)SYN_RCVD → ESTABLISHED

一句话记忆:

客户端先问(SYN),服务器回应并反问(SYN+ACK),客户端最后确认(ACK)

核心要点:

  • 目的:确认收发能力 + 同步序列号 + 协商参数
  • 最少 3 次:防止旧 SYN 包误开连接
  • 序列号随机:安全 + 防冲突
  • 半连接队列:SYN Flood 攻击目标

掌握 TCP 三次握手,是理解网络编程、性能优化和排查网络问题的第一步。


🌺The End🌺点点关注,收藏不迷路🌺

⬆ ⬆ 顶部 ⬆ ⬆
http://www.jsqmd.com/news/922978/

相关文章:

  • 基于BeagleBone Black与BLE 5.0的物联网设备开发实践
  • 易拉罐DIY AM天线:从材料替代到信号增强的无线电实践
  • 如何用BiRefNet实现高精度图像分割:新手完整指南
  • 别再为WVP-PRO和ZLM重启循环头疼了!一个配置修改搞定服务稳定连接
  • 基于Spring MVC的三角形测试系统设计与实现
  • 高三英语只有70分还有救吗?低分逆袭靠谱教育机构实测推荐 - 品牌测评鉴赏家
  • 为什么有些人表面嫌弃别人脏,自己家苍蝇满天飞的叮咬食物,也不嫌弃自己脏,为什么这样双标?
  • 物理服务器装CentOS 7.9,从BIOS设置到分区规划保姆级避坑指南
  • 避坑指南:Unity 2020做VR,Shader报错‘sampler_CameraDepthTexture’的终极解法
  • 终极指南:在Windows上完美使用PS3手柄的DsHidMini虚拟HID驱动
  • 为什么AI越强,内容审核反而越难了?深度拆解社交媒体平台内容治理技术架构
  • BetterNCM安装器:Rust构建的网易云插件管理终极方案
  • 【并发Web服务器】手写百万并发Web服务器详解:整合Epoll+线程池+内存池,从零搭建工业级HTTP服务,打通计算机底层全栈闭环
  • 2026西安黄金回收店最放心排名前十盘点!内行人实测:哪家报价最透明、最靠谱不压价? - 西安闲转记
  • 广州海珠区设备搬运公司哪家专业靠谱?2026 实测测评 - 从来都是英雄出少年
  • 2026 广州海珠区搬运公司口碑榜 街坊亲测不踩坑 - 从来都是英雄出少年
  • 如何快速配置Python自动化抢票工具:终极使用指南
  • 口袋妖怪存档管理革命:PKSM 10.2.2版本深度解析与实战指南
  • 如何免费下载无水印快手视频?KS-Downloader完整指南教你快速掌握
  • 基于Arduino的智能宠物喂食器:从传感器到伺服电机的完整物联网项目实践
  • Unity 2D游戏开发避坑指南:搞定Tilemap等距视角渲染与碰撞设置
  • 电子厂最常见应用
  • 高三数学常年不及格?最后一年逆袭提分攻略|靠谱家教机构实测推荐 - 品牌测评鉴赏家
  • 告别网盘限速烦恼:LinkSwift 直链下载助手使用指南
  • 实话直说!两个月从二本冲到一本,真的不是天方夜谭|靠谱机构实测推荐 - 品牌测评鉴赏家
  • 深度探索Pearcleaner:如何让Mac应用清理变得智能又彻底?
  • 2026 广州吊装公司推荐 高难度设备搬迁起重避坑全攻略 - 从来都是英雄出少年
  • Gemini对话写作跃迁指南:从机械复述到人格化表达的4阶认知升级路径
  • APC聚类与加权质心指纹:优化室内定位精度与效率的工程实践
  • 基于Arduino与NeoPixel的智能情绪灯:从环境感知到灯光交互