Node.js 网络层:Socket、TCP 与 UDP 心智
HTTP 那篇站在
http.Server这一层。再往下,是 TCP 连接、字节流、粘包拆包——很多长连接、游戏、自定义协议都停在这一层。
这一篇想讲清楚几件事:net模块在管什么、TCP 流和 HTTP「请求」有什么差别、UDP 什么时候该用不该用,以及和前面 Stream、Buffer 两条线怎么接上。
net:在操作系统 socket 上包一层
net.createServer 创建 TCP 服务器;每个新连接是一个 net.Socket:
Socket既是 可读流也是可写流(Duplex);- 读出来、写进去的都是 字节(默认 Buffer)。
所以 TCP 在 Node 里首先是流:没有天然的「一条消息」边界,只有 连续字节。
TCP 字节流:粘包、半包、要自己定界
和 HTTP 不同:
- HTTP 有 头 + Content-Length / chunked,框架帮你 切成「请求」;
- 裸 TCP 里,应用协议要自己定义:
- 固定长度、
- 长度前缀、
- 分隔符、
- 或上层用 Protobuf / MessagePack 等。
若忘了这一层:
- 会出现 「读到的 chunk 不等于一条业务消息」;
- 或 把两条消息粘在一起解析。
心智模型:TCP 保证顺序与可靠(在连接存活前提下),不保证「消息」。
net.connect / Socket:客户端长连接
客户端用 net.connect(port, host) 拿到 Socket,同样按 流 读写。
常见用途:
- 数据库协议驱动、Redis 协议、自定义 RPC;
- 与硬件/内网服务 打交道的二进制协议。
关闭连接时要注意:
endvsdestroy:优雅半关闭 vs 硬断;- 错误事件 必须处理,否则未处理异常会顶掉进程。
UDP:dgram 与「消息」边界
dgram 模块处理 UDP:
- 每次
message事件 通常对应 一个 datagram(有消息边界); - 不保证可靠、不保证顺序。
适合:
- 可丢、要低延迟、广播/发现 类场景;
- 或上层自己 做重传与排序。
不适合:
- 默认就想当 TCP 用——那是在重复造轮子。
和 HTTP / WebSocket 的关系
可以叠一张层次图:
- 应用协议(HTTP、WebSocket 帧);
- TLS(可选);
- TCP(
net); - IP / 网卡。
WebSocket 在浏览器侧常见,在 Node 里往往用 库 处理握手与帧;底层仍然长 TCP 连接。理解 net.Socket 有助于排查 连接泄漏、半开连接、背压。
小结:先会字节流,再谈业务协议
net.Socket是 Duplex 流,读写单位是 字节;- TCP 无消息边界,协议要自己 定界;
- UDP 有报文边界,但 不可靠,选型要匹配业务容忍度;
- HTTP 是跑在 TCP 上的 文本起始协议,框架帮你拆好了「请求」。
把这一层和 Buffer + Stream 一起看,自定义协议、网关、代理、抓包对照,会顺很多。