在 Linux 上做 Node.js 网络开发,最常见的问题不是“能不能做”,而是“该从哪一层开始”。同样是监听端口、收发数据,原生 http、Express、WebSocket 和 net 模块面对的其实是四类不同需求。下面按使用场景拆开说明,并保留可直接运行的示例代码,帮助你判断什么时候该用高层封装,什么时候该回到底层协议。
用原生 http 快速启动 Web 服务
如果只是想在 Linux 上快速起一个最基础的 Web 服务,Node.js 内置的 http 模块已经够用,不需要额外安装第三方依赖。它适合拿来理解请求、响应和端口监听这些最基本的网络通信过程。
下面这段代码会创建一个监听 3000 端口的 HTTP 服务器,请求到来时返回纯文本 Hello World:
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Hello Worldn');
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
这一层的优点是直接、依赖少,适合做简单接口、学习服务端处理流程,或者临时验证网络环境是否正常。但一旦项目开始涉及多路由、参数处理、中间件和错误管理,直接使用原生模块就会明显变得吃力。
需要路由和中间件时,优先考虑 Express
真实项目里,开发者通常不会长期用原生 http 模块手写路由。更常见的做法是引入 Express.js,把路由、中间件和请求处理交给更清晰的应用层框架。
先安装依赖:
npm install express
再写一个最小可运行的示例:
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
和原生 http 相比,Express 的核心价值不在“能不能起服务”,而在于它把接口开发中最常见的工作抽象好了。对于 REST API、后台服务、管理系统接口这类场景,Express 往往是更省事的起点。
Express 适合什么场景
如果你的服务需要清晰的 URL 路由、统一中间件处理、后续继续扩展认证或日志能力,Express 会比原生模块更合适。文章里提到的高并发 REST API,也是它常见的使用方向之一。
要做实时双向通信,可以用 WebSocket
当应用需要低延迟、双向通信时,HTTP 的“请求一次、响应一次”模型就不够用了。聊天、消息推送、在线协作这类场景,更适合使用 WebSocket。Node.js 生态里,ws 是常见且主流的选择。

先安装依赖:
npm install ws
下面是一个最基础的 WebSocket 服务端示例。客户端连接后,只要收到消息,就原样回一条确认内容:
// server.js
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 3000 });
wss.on('connection', (ws) => {
ws.on('message', (message) => {
console.log(`Received message: ${message}`);
ws.send(`You sent: ${message}`);
});
});
对应的客户端代码如下:
// client.js
const WebSocket = require('ws');
const ws = new WebSocket('ws://localhost:3000');
ws.on('open', () => {
ws.send('Hello Server!');
});
ws.on('message', (message) => {
console.log(`Received message: ${message}`);
});
这个例子展示的重点,不是复杂业务逻辑,而是 WebSocket 的通信方式:连接建立后,客户端和服务端都可以主动发消息,不必像 HTTP 那样每次都由客户端先发起请求。
什么时候该选 WebSocket
如果业务核心在“实时状态变化”,比如聊天、通知推送、实时面板、多人协作,那么 WebSocket 通常比普通 HTTP 接口更自然。文章中也提到,类似需求下它往往是首选方案。
需要底层协议控制时,直接使用 net 模块
如果你面对的不是 HTTP 服务,而是更底层的套接字通信,Node.js 自带的 net 模块就很重要了。它提供 TCP 通信能力,适合处理自定义协议,或者连接其他非 HTTP 服务。
先看服务端代码:
// server.js
const net = require('net');
const server = net.createServer((socket) => {
socket.write('Hello from server!n');
socket.on('data', (data) => {
console.log(`Received message: ${data}`);
socket.write(`You sent: ${data}`);
});
});
server.listen(3000, () => {
console.log('Server listening on port 3000');
});
再看客户端:
// client.js
const net = require('net');
const client = net.createConnection({ port: 3000 }, () => {
console.log('Connected to server');
client.write('Hello from client!');
});
client.on('data', (data) => {
console.log(`Received message: ${data}`);
});
和 HTTP、WebSocket 相比,TCP 的抽象层更低,也更灵活。它不替你定义请求格式、路由规则或消息语义,这意味着你可以自己设计协议,但也要自己处理更多细节。
TCP 更适合哪些任务
当你需要和已有的 TCP 服务通信,或者项目本身就是私有协议、设备通信、网关转发这类低层场景时,net 模块会更贴近需求。它不是更“高级”的方案,而是更底层、控制权更大的方案。
Linux 上该怎么选 Node.js 网络方案
把这几种方式放在一起看,选择思路其实很清楚:

- 只想快速跑一个基础 Web 服务:用原生
http模块。 - 要开发结构化 API、处理路由和中间件:用 Express。
- 要做双向、低延迟实时通信:用 WebSocket,常见实现是
ws。 - 要处理底层 TCP、自定义协议或非 HTTP 服务:用
net模块。
除了这些基础选项,社区里还有 Koa、Fastify、Socket.IO 等更成熟或更偏工程化的方案。但如果先把本文这几类基础能力理解清楚,再去看上层框架,判断成本和学习曲线都会低很多。







