3、网络基础回顾(下):TCP三次握手与四次挥手、UDP协议特点、HTTP/HTTPS协议详解

好,咱们接着聊。上一节我们把网络分层和IP路由讲透了,这一节我带你看看传输层和应用层的几个核心协议。说白了,你写的加速器代码,最终就是在跟这些协议打交道。不理解它们,你连数据怎么丢的、怎么重传的都搞不清楚。

3.1 TCP三次握手:连接是怎么建立的?

TCP是面向连接的协议。什么叫“面向连接”?就是通信前,双方先打个招呼,确认“我准备好了,你呢?”——这个过程就是三次握手。

我刚开始写网络程序时,总觉得三次握手是教科书上的东西,实际用不到。直到有一次我在生产环境排查一个连接超时问题,抓包一看,客户端发出去的SYN石沉大海,服务器根本没回。嗯,那时候我才意识到,握手失败是线上最常见的故障之一。

三次握手的流程,我习惯用这个图来记:

客户端 服务端 CLOSED LISTEN ① SYN=1, seq=x SYN_SENT ② SYN=1, ACK=1, seq=y, ack=x+1 SYN_RCVD ③ ACK=1, seq=x+1, ack=y+1 ESTABLISHED ESTABLISHED

流程其实很简单:

  • 第一次握手:客户端发SYN包,告诉服务器“我想连你”。客户端进入SYN_SENT状态。
  • 第二次握手:服务器回SYN+ACK,表示“收到,我也准备好了”。服务器进入SYN_RCVD状态。
  • 第三次握手:客户端发ACK确认,“好,开始传数据吧”。双方进入ESTABLISHED状态。
避坑指南:我曾经遇到过一个诡异的问题——客户端连服务器偶尔超时,但又不是每次都失败。抓包后发现,服务器在第二次握手后,客户端的ACK丢了。服务器没收到确认,就一直重发SYN+ACK。而客户端以为连接已经建立了,开始发数据。结果两边状态不一致,数据全丢了。解决方案?调整tcp_syn_retries参数,别让服务器等太久。

3.2 TCP四次挥手:优雅地断开连接

有连接就有断开。四次挥手就是TCP的“分手流程”。你想想看,为什么是四次而不是三次?因为TCP是全双工的,两边都要独立关闭自己的数据通道。

流程是这样的:

  1. 第一次挥手:主动方发FIN,表示“我这边没数据要发了”。主动方进入FIN_WAIT_1状态。
  2. 第二次挥手:被动方回ACK,“知道了,但我还有数据要发”。主动方进入FIN_WAIT_2状态。
  3. 第三次挥手:被动方数据发完了,发FIN,“我也没数据了”。被动方进入LAST_ACK状态。
  4. 第四次挥手:主动方回ACK,“收到,拜拜”。主动方进入TIME_WAIT状态,等2MSL后关闭。
注意:TIME_WAIT状态是个坑。主动关闭连接的一方会在这个状态停留2MSL(约2分钟)。如果你写的是高并发服务器,频繁主动关闭连接会导致大量TIME_WAIT堆积,端口被占满。我有个项目就因为这个原因,压测到一半服务器拒绝新连接了。解决办法?要么调整tcp_tw_reuse,要么让客户端主动关闭。

3.3 UDP协议特点:简单粗暴,但快

UDP和TCP完全是两个极端。TCP像快递——要签收、要确认、丢了重发。UDP像扔飞镖——扔出去就不管了,对方接没接到随缘。

UDP的核心特点就三个:

  • 无连接:不需要握手,直接发数据。延迟低,适合实时应用。
  • 不可靠:不保证送达,不保证顺序。丢了就丢了,不会重传。
  • 无状态:服务器不需要维护连接表,资源消耗小。

那UDP有什么用?你想想看,视频通话、在线游戏、DNS查询——这些场景对实时性要求高,偶尔丢一帧画面没关系,但卡顿是不能接受的。这时候UDP就派上用场了。

我的经验:做加速器时,UDP的穿透性比TCP好得多。因为UDP无状态,NAT设备更容易处理。我曾经用UDP做P2P打洞,成功率比TCP高30%以上。但代价是——你得自己在应用层实现重传和排序。说白了,UDP把“可靠性”这个包袱甩给了开发者。

3.4 HTTP/HTTPS协议详解

HTTP是应用层最常用的协议。你每天刷网页、看视频、调API,底层都是HTTP在跑。但很多人对它的理解停留在“发个请求,收个响应”这个层面。

咱们深入一点。

3.4.1 HTTP请求结构

一个HTTP请求由三部分组成:

  • 请求行:方法 + URL + 协议版本。比如 GET /index.html HTTP/1.1
  • 请求头:一堆键值对,告诉服务器你的浏览器、语言、cookie等信息。
  • 请求体:POST请求时携带的数据,比如表单内容或JSON。

举个例子:

POST /api/login HTTP/1.1
Host: example.com
Content-Type: application/json
User-Agent: Mozilla/5.0
Content-Length: 45

{"username":"admin","password":"123456"}

3.4.2 HTTP响应结构

响应也类似:

  • 状态行:协议版本 + 状态码 + 状态描述。比如 HTTP/1.1 200 OK
  • 响应头:服务器信息、内容类型、缓存策略等。
  • 响应体:实际返回的数据,可能是HTML、JSON、图片等。

状态码我建议你背下来,面试常考,线上排查也常用:

状态码 含义 常见场景
200 OK 请求成功
301/302 重定向 URL变更,跳转到新地址
400 Bad Request 参数错误,服务器看不懂
401 Unauthorized 没登录或token过期
403 Forbidden 有登录但没权限
404 Not Found 资源不存在
500 Internal Server Error 服务器内部炸了
502 Bad Gateway 网关或代理后端挂了
503 Service Unavailable 服务器过载或维护中

3.4.3 HTTPS:给HTTP加把锁

HTTP是明文传输的。你想想看,在公共WiFi下,你发的每个请求、每个密码,都像在广播里喊出来一样。任何人都能抓包看到。

HTTPS就是在HTTP外面套了一层TLS/SSL加密。流程大致是:

  1. 客户端请求服务器证书。
  2. 服务器返回证书(包含公钥)。
  3. 客户端验证证书合法性(CA签名)。
  4. 客户端生成对称密钥,用公钥加密后发给服务器。
  5. 双方用对称密钥加密通信。
核心要点:HTTPS用了两种加密方式——非对称加密(握手阶段)和对称加密(数据传输阶段)。非对称加密慢,但适合安全交换密钥;对称加密快,适合大量数据传输。两者结合,既安全又高效。
避坑指南:我曾经遇到一个HTTPS性能问题——服务器CPU飙高,QPS上不去。排查后发现,每次握手都要做一次非对称加解密,太耗CPU了。解决方案?启用TLS会话复用(Session Resumption),让客户端和服务端缓存握手结果,下次直接复用。QPS直接翻了一倍。

3.5 本章小结

这一节我们聊了TCP的握手与挥手、UDP的简单粗暴、HTTP/HTTPS的请求响应结构。这些知识是网络加速器开发的基石。你写代理、做转发、优化连接,都离不开对它们的理解。

嗯,内容不少,但都是干货。下一节我们开始动手——搭建开发环境,写第一个网络程序。


公众号:蓝海资料掘金营,微信deep3321