TCP 发送应用数据之前,必须在连接两端建立状态。该设置过程就是 TCP 三向握手。它发生得如此之快,以至于大多数用户从未注意到它,但是当网站感觉缓慢、端口似乎关闭或防火墙以奇怪的方式破坏应用程序时,握手通常就是故事的开始。
TCP 三向握手
这三个数据包是:
- 同步 来自客户
- 同步确认 来自服务器
- 确认 来自客户
之后,连接建立并开始正常数据传输。
逐步说明
1.客户端发送SYN
客户端实际上是说,“我想启动一个连接,这是我的初始序列号。”
2. 服务器回复SYN-ACK
The server acknowledges the client's sequence number and sends its own starting sequence number back.
3. 客户端发送ACK
客户端确认服务器的序列号。此时双方就可靠地交换数据所需的基本状态达成一致。
为什么TCP需要握手
握手不仅仅是仪式。它解决了实际的协议问题:
- 确认两个端点都可以发送和接收
- 协商初始序列跟踪
- 防止旧会话的延迟数据包被误认为当前流量
- 建立可靠交付所需的状态
如果没有此设置,TCP 无法提供应用程序期望的有序、可靠的流行为。
为什么 TCP 使用三步而不是两步
两步交换并不能完全证明双方已准备好传输并确认对方的序列号。第三个数据包确认已收到服务器的答复,并且连接状态在两个方向上都是同步的。
这就是为什么握手是“三向”的,而不仅仅是请求-响应对。
握手失败会发生什么
握手失败通常分为几种可识别的模式。
SYN 已发送,无回复
可能原因:
- 目标主机宕机
- 防火墙正在默默地丢弃数据包
- IP或端口错误
- 路径中的路由问题
常见症状:
- 连接超时
- 浏览器旋转一段时间,然后失败
telnet或客户端应用程序在放弃之前挂起
SYN 发送,RST 返回
可能原因:
- 端口已关闭
- 服务未监听
- 防火墙配置为拒绝而不是丢弃
常见症状:
- 立即“连接被拒绝”
SYN 和 SYN-ACK 出现,然后会话终止
可能原因:
- 非对称路由 续订时
- 状态防火墙问题
- 损坏的 NAT 设备
- 负载均衡器配置错误
- 基于主机的安全产品在初始接受后产生干扰
Wireshark 中的握手是什么样子的
如果您在 Wireshark 中捕获流量,健康的 TCP 启动通常如下所示:
SYNSYN, ACKACK
如果您只看到重复重传的 SYN 数据包,则服务器回复永远不会返回。如果您看到 RST,则目标主动拒绝了连接。这种可见性就是数据包捕获对于网络故障排除如此有用的原因。
为什么握手对性能很重要
每个 TCP 连接在数据流开始之前至少开始一次往返。
如果延迟为 100 毫秒:
- 握手费用大约是一个来回
- TLS 之后添加了更多协商
- 短暂的连接感觉明显变慢
这是现代性能调优关心连接重用、HTTP 保持活动行为、CDN 以及 HTTP/2 和 HTTP/3 等协议的原因之一。
TCP 握手和 TLS 不是一回事
这是一个常见的混乱来源。
- TCP 握手 建立传输连接。
- TLS 握手 在该连接之上协商加密和证书信任。
所以当你打开HTTPS网站时,系统通常会执行:
- TCP 握手
- TLS 握手
- HTTP 请求和响应
如果站点“开始加载”速度很慢,则延迟可能出现在任一握手层中。
Relationship to Port Scanning
许多扫描仪依赖于握手行为:
- 同步确认 通常表示端口开放
- RST 通常表示关闭
- 没有反应 通常意味着过滤或丢弃
这使得握手不仅是网络的核心,也是枚举和安全测试的核心。
SYN 洪水攻击
SYN 洪水通过发送大量 SYN 数据包而不完成最终 ACK 来滥用握手。服务器为许多半开会话分配资源,并且可能会变得不堪重负。
常见缓解措施:
- SYN cookies
- 速率限制
- 上游过滤
- 防火墙保护
- 负载均衡器调整
连接拆卸不同
启动会话使用三向握手。关闭它通常使用涉及双向 FIN 和 ACK 数据包的不同过程。
当调试套接字陷入困境时,拆卸很重要 TIME_WAIT 或 CLOSE_WAIT,但它与初始连接握手是分开的。
底线
TCP 握手是可靠 TCP 通信的三步启动:
- 同步
- 同步确认
- 确认
这很重要,因为基于 TCP 构建的每个 Web 请求、SSH 会话、数据库连接或 API 调用都依赖于它。如果连接超时、被拒绝或在任何数据移动之前感觉很慢,则握手是首先要调查的地方之一。