所有 HTTP 通信在建立 TCP 连接时都必须经过三次握手*。下面用最直白的方式讲清楚:
为什么需要三次握手?
TCP 是可靠传输协议 ,必须确保客户端和服务器双方都能正常收发数据。三次握手的核心目的是:
同步双方的初始序列号(ISN) + 确认双方收发能力正常。
三次握手过程(以客户端 → 服务器为例)
假设客户端 IP: A,服务器 IP: B
| 步骤 | 方向 | 报文标志位 | 关键动作 |
|---|---|---|---|
| 1 | A → B |
SYN=1 |
客户端发送 SYN 包 (seq=x),请求建立连接,并进入 SYN_SENT 状态。 |
| 2 | B → A |
SYN=1, ACK=1 |
服务器回复 SYN+ACK 包 (seq=y, ack=x+1),进入 SYN_RCVD 状态。 |
| 3 | A → B |
ACK=1 |
客户端发送 ACK 包 (ack=y+1),双方进入 ESTABLISHED 状态,连接建立完成。 |
✅ 关键点:
- SYN(Synchronize):同步序列号
- ACK(Acknowledgment):确认收到对方的 SYN
- seq(序列号):自己发送数据的起始编号
- ack(确认号):期望对方下次发送的序列号(= 对方 seq + 1)
为什么必须是三次?两次行不行?
不行! 两次握手会导致 历史连接请求突然到达服务器,造成资源浪费 (经典"已失效请求 "问题)。
三次握手能确保双方都确认了对方的收发能力:
- 客户端确认:自己能发 + 服务器能收能发
- 服务器确认:自己能发 + 客户端能收能发
🌰 举个栗子:
如果只有两次握手,客户端发送的旧 SYN 包(因网络延迟)突然到达服务器,服务器会误以为是新连接并分配资源,但客户端早已不要这个连接了 → 资源泄漏。
和 HTTP 的关系
- 当你在浏览器输入
http://example.com时:
1️⃣ 先通过 DNS 解析域名 → IP
2️⃣ 三次握手建立 TCP 连接 (目标端口 80)
3️⃣ 在已建立的 TCP 连接上发送 HTTP 请求 (GET/POST 等)
4️⃣ 服务器返回 HTTP 响应
5️⃣ (可选)四次挥手断开连接
🔒 HTTPS 额外步骤 :
TCP 三次握手后,还要进行 TLS 握手(交换密钥、验证证书等),之后才开始 HTTP 通信。
常见问题
Q:SYN Flood 攻击是什么?
A:攻击者伪造大量 SYN 包(不完成第三次握手),耗尽服务器连接队列资源 → 拒绝服务(DoS) 。
防御:SYN Cookie、限制半连接队列长度等。
Q:为什么挥手要四次?
A:因为 TCP 是全双工的,双方需要独立关闭自己的发送通道(后续可展开)。
这是个非常好的问题!你抓住了"短连接"这个术语容易让人困惑的地方。
✅ 核心结论:
"短连接"不是指 TCP 连接存在的时间绝对很短,而是指"一次请求-响应完成后就主动关闭连接" ,
与之相对的是"长连接 "------即复用同一个 TCP 连接发送多次 HTTP 请求/响应。
📌 详细解释:
1. 所有 TCP 连接都会在某个时刻结束
无论是短连接还是长连接,TCP 连接最终都要通过"四次挥手"关闭 。
所以"等到结束才结束"是所有 TCP 连接的共性,不能用来区分长短连接。
2. 什么是"短连接"(Short-lived Connection)?
- 每次 HTTP 请求 都:
- 建立 TCP 连接(三次握手)
- 发送 HTTP 请求
- 接收 HTTP 响应
- 立即关闭 TCP 连接(四次挥手)
- 下一次请求 → 重新建立新连接
💡 典型场景 :早期 HTTP/1.0 默认行为(除非显式设置
Connection: keep-alive)
✅ 优点:简单、资源释放及时
❌ 缺点:频繁握手/挥手开销大(尤其 HTTPS 还要 TLS 握手),延迟高
3. 什么是"长连接"(Persistent Connection)?
- 一个 TCP 连接上 可以:
- 发送多个 HTTP 请求
- 接收多个 HTTP 响应
- 连接保持打开一段时间 (由
Keep-Alive超时时间决定,如 30s/60s) - 超时无新请求 → 自动关闭;或主动发送
Connection: close关闭
💡 典型场景 :HTTP/1.1 默认启用长连接 (除非显式设置
Connection: close)
✅ 优点:减少 TCP/TLS 握手次数 ,提升性能、降低延迟
❌ 缺点:服务器需维护连接状态,占用资源
🌰 举个实际例子:
| 行为 | 短连接 | 长连接 |
|---|---|---|
| 请求 1 | 建连 → 发请求 → 收响应 → 断连 | 建连 → 发请求 → 收响应 |
| 请求 2 | 重新建连 → ... → 断连 | 复用原连接 → 发请求 → 收响应 |
| 请求 3 | 再次建连 → ... → 断连 | 继续复用 → 发请求 → 收响应 |
| 总 TCP 连接数 | 3 次 | 1 次(直到超时或关闭) |
🔍 为什么叫"短"?
- "短"指的是连接的"生命周期"仅覆盖单次请求-响应,用完就扔。
- 而"长"连接的生命周期跨越多次请求,持续更"久"。
⏱️ 注意:这里的"短"/"长"是相对行为模式而言 ,不是绝对时间。
比如一个短连接可能因为网络慢持续了 2 秒,而一个长连接在 100 毫秒内就处理完所有请求并关闭了------但前者仍是"短连接",后者是"长连接"。
💡 补充:HTTP/2 和 HTTP/3 的演进
- HTTP/2 :强制单连接多路复用(一个 TCP 连接上并行处理多个请求),彻底告别短连接。
- HTTP/3 :基于 UDP + QUIC,连接迁移、0-RTT 建连,进一步优化。
✅ 总结一句话:
"短连接" = 一次 HTTP 事务(请求+响应)用一个独立 TCP 连接,用完即关;
"长连接" = 一个 TCP 连接被多个 HTTP 事务复用。
这就是为什么即使 TCP 连接"等到结束才结束",只要它只服务一次请求,就叫"短连接"。