Node.js 网络层:Socket、TCP 与 UDP 心智

HTTP 那篇站在 http.Server 这一层。再往下,是 TCP 连接、字节流、粘包拆包——很多长连接、游戏、自定义协议都停在这一层。
这一篇想讲清楚几件事:net 模块在管什么、TCP 流和 HTTP「请求」有什么差别、UDP 什么时候该用不该用,以及和前面 Stream、Buffer 两条线怎么接上。

net.createServer 创建 TCP 服务器;每个新连接是一个 net.Socket

  • Socket 既是 可读流也是可写流(Duplex);
  • 读出来、写进去的都是 字节(默认 Buffer)。

所以 TCP 在 Node 里首先是流:没有天然的「一条消息」边界,只有 连续字节

和 HTTP 不同:

  • HTTP头 + Content-Length / chunked,框架帮你 切成「请求」
  • 裸 TCP 里,应用协议要自己定义:
    • 固定长度、
    • 长度前缀、
    • 分隔符、
    • 或上层用 Protobuf / MessagePack 等。

若忘了这一层:

  • 会出现 「读到的 chunk 不等于一条业务消息」
  • 把两条消息粘在一起解析

心智模型:TCP 保证顺序与可靠(在连接存活前提下),不保证「消息」

客户端用 net.connect(port, host) 拿到 Socket,同样按 读写。

常见用途:

  • 数据库协议驱动Redis 协议自定义 RPC
  • 与硬件/内网服务 打交道的二进制协议。

关闭连接时要注意:

  • end vs destroy:优雅半关闭 vs 硬断;
  • 错误事件 必须处理,否则未处理异常会顶掉进程。

dgram 模块处理 UDP

  • 每次 message 事件 通常对应 一个 datagram(有消息边界);
  • 不保证可靠、不保证顺序

适合:

  • 可丢要低延迟广播/发现 类场景;
  • 或上层自己 做重传与排序

不适合:

  • 默认就想当 TCP 用——那是在重复造轮子。

可以叠一张层次图:

  • 应用协议(HTTP、WebSocket 帧);
  • TLS(可选);
  • TCPnet);
  • IP / 网卡

WebSocket 在浏览器侧常见,在 Node 里往往用 处理握手与帧;底层仍然长 TCP 连接。理解 net.Socket 有助于排查 连接泄漏、半开连接、背压

  • net.SocketDuplex 流,读写单位是 字节
  • TCP 无消息边界,协议要自己 定界
  • UDP 有报文边界,但 不可靠,选型要匹配业务容忍度;
  • HTTP 是跑在 TCP 上的 文本起始协议,框架帮你拆好了「请求」。

把这一层和 Buffer + Stream 一起看,自定义协议、网关、代理、抓包对照,会顺很多。