当前位置:首页 > 娱乐

nodejs net模块

Node.js net模块:比想象中更底层的网络工具

大多数Node.js开发者对`http`模块耳熟能详,却很少直接碰`net`模块。这有点可惜——`net`才是Node网络能力的真正地基。它直接封装了TCP/IP协议栈,没有HTTP那层繁文缛节。你发送什么,对方就收到什么,连一个额外的字节都不会加。

我最初接触`net`是为了写一个内网穿透工具。当时用HTTP做代理,延迟高得让人抓狂。换成`net.createConnection`后,延迟直接砍掉一半。原因很简单:HTTP的每个请求都要经过解析、封装、再解析的过程,而TCP连接一旦建立,就是纯粹的数据流管道。

看一段最基础的代码:

const net = require('net'); const server = net.createServer(socket => {  socket.on('data', chunk => {  socket.write('echo: ' + chunk); }); }); server.listen(8080);

七行代码,一个可用的TCP回显服务器。没有路由,没有中间件,没有请求对象。`socket`就是一个双向数据流,像一根水管,你往里面灌什么,它就流什么。这种原始感反而让人上瘾——你终于能精确控制网络上传输的每一个比特。

`net`模块最实用的场景是处理自定义协议。比如很多硬件设备(POS机、门禁控制器、工业传感器)都走裸TCP协议。它们的报文格式往往是固定长度的二进制头加上可变长度的数据段。用HTTP根本没法解析这种流式数据,而`net`配合`Buffer`可以逐字节处理。

我帮朋友调过一个智能水表的数据采集程序。水表每30秒上报一次数据,报文格式是:前4字节是长度,后面跟着JSON字符串。用`net`写起来特别清爽:

let buffer = Buffer.alloc(0); socket.on('data', chunk => {  buffer = Buffer.concat([buffer, chunk]); while (buffer.length >= 4) {  const msgLen = buffer.readUInt32BE(0); if (buffer.length < 4 + msgLen) break; const json = buffer.slice(4, 4 + msgLen).toString(); handleReport(JSON.parse(json)); buffer = buffer.slice(4 + msgLen); } });

注意那个`while`循环——TCP是流协议,一次`data`事件可能包含半个报文,也可能包含三个完整报文。这种粘包和拆包的处理,是`net`编程的必修课。HTTP帮你做了这件事,但代价是你失去了对底层行为的控制。

另一个有意思的功能是`server.close()`之后的回调时机。你以为关闭服务器就完事了,实际上已建立的连接还活着。你得手动遍历所有`socket`并调用`destroy()`。这个细节坑过不少人——我见过生产环境里因为没处理这个,导致旧连接一直占着内存,最后进程崩溃。

`net`模块还支持IPC(进程间通信)。`server.listen('/tmp/app.sock')`就能创建一个Unix域套接字。这种方式比TCP回环快得多,因为没有网络栈的开销。在单机多进程架构里,用`net`做进程间通信比用HTTP或消息队列都轻量。不过要注意,Windows不支持Unix域套接字,跨平台代码得做条件判断。

如果你做的是纯后端服务,`net`的性能优势更明显。Node官方基准测试里,`net`的吞吐量大约是`http`的3到5倍。原因很直白:HTTP解析器本身就是CPU密集型的。而`net`只是搬运字节,几乎不消耗额外资源。我在一台2核4G的云服务器上,用`net`写了个日志收集服务,稳定扛住了每秒2万条日志写入,CPU使用率不到40%。换成HTTP实现,同样负载下CPU直接飙到80%以上。

但`net`不适合所有场景。需要路由、缓存、认证这些高层能力时,还是得回到`http`或`express`。`net`给你的是一把手术刀,不是瑞士军刀。你得自己处理连接管理、心跳检测、断线重连这些脏活。好在Node社区有现成模式可参考:用`setTimeout`做空闲超时,用`socket.on('error')`捕获异常连接,用`TCP_NODELAY`禁用Nagle算法来降低延迟。

最后说个冷知识:`https`模块底层依赖的是`tls`模块,而`tls`模块又是基于`net`实现的。也就是说,你写的每个HTTPS请求,最终都跑在`net`构建的TCP流上。理解了`net`,你才算真正看懂了Node的网络模型。

下次遇到网络瓶颈时,别急着加服务器。先想想能不能用`net`绕过HTTP那层开销——也许答案就藏在原始的字节流里。

分享到: