Node.js用net模块监听TCP端口最直接:必须显式绑定'0.0.0.0'而非默认127.0.0.1,否则远程及VSCode端口转发均无法连接;HTTP服务器不处理裸TCP流量,需用net.createServer()创建原始字节流服务。

Node.js 用 net 模块监听 TCP 端口最直接
VSCode 本身不监听 TCP 流量,它只是编辑器;真正监听端口的是你写的 Node.js 程序。要用 Node 监听 TCP,必须用内置的 net 模块——不是 http,也不是 Express。前者处理原始字节流,后者只管 HTTP 协议。
常见错误是误用 app.listen(3000) 想抓 TCP 包,结果连不上:HTTP 服务器默认只响应 HTTP 请求,对 telnet、nc 或自定义 TCP 客户端发来的纯二进制数据直接断连。
-
net.createServer()创建的是裸 TCP 服务,收发都是Buffer,适合调试协议、对接嵌入式设备或做代理 - 监听地址必须显式写成
'0.0.0.0',否则默认绑定127.0.0.1,远程或 VSCode 端口转发后也连不上 - 端口被占时,
server.listen()会抛EADDRINUSE错误,不是静默失败;别靠“没报错就以为成功了”
最小可用示例:
const net = require('net');
const server = net.createServer(socket => {
socket.write('Connected\r\n');
socket.on('data', chunk => console.log('←', chunk.toString()));
socket.on('end', () => console.log('Client disconnected'));
});
server.listen(8080, '0.0.0.0', () => console.log('TCP server on :8080'));
VSCode 调试时端口冲突的典型表现和清理动作
你在终端里跑 node server.js,VSCode 同时启动调试(比如用 launch.json 的 launch 模式),两个进程可能同时尝试 bind 同一个端口,导致第二个报 Error: listen EADDRINUSE: address already in use :::8080。
这不是配置问题,是系统级资源争抢。别急着改代码端口,先确认谁在占:
- macOS/Linux:
lsof -ni :8080→ 看 PID,再kill 1234(先软杀),等 2 秒无响应再kill -9 1234 - Windows PowerShell:
Get-NetTCPConnection -LocalPort 8080→ 取OwningProcess,然后taskkill /f /t /pid 1234(必须带/t杀子树) - VSCode 自家残留进程也要清:
killall -r "Code Helper|Electron"(macOS/Linux)或taskkill /f /t /im Code.exe(Windows)
验证是否清干净:lsof -i :8080 或 Get-NetTCPConnection -LocalPort 8080 返回空才安全。
根据 package.json 中的 engines 字段自动检测 Node.js 版本需求,未安装 nvm 时自动安装并切换至对应版本。支持 Windows、macOS、Linux。适用于 Node.js 项目开发、版本切换和环境配置。
Remote-SSH 下 TCP 服务必须监听 0.0.0.0 才能被转发
你在远程服务器上跑 Node TCP 服务,本地用 VSCode Remote-SSH 连过去,然后点「Forward Port」,结果浏览器或 telnet 死活连不上 —— 大概率是服务只绑了 localhost 或 127.0.0.1。
SSH 端口转发本质是把远程机器的网络栈某端口流量,经加密隧道拉到本地。但如果远程服务压根没监听外部接口,转发过来也没人收。
- 错的写法:
server.listen(8080)→ 默认等价于server.listen(8080, '127.0.0.1') - 对的写法:
server.listen(8080, '0.0.0.0')或server.listen(8080, '::')(IPv6 兼容) - VSCode Remote-SSH 的自动转发只识别已建立连接的端口,不会主动帮你改监听地址;它不干预你的代码逻辑
顺手验证:登录远程服务器,执行 ss -tln | grep :8080(Linux)或 netstat -an | findstr :8080(Windows),看 Local Address 列是不是 *:8080 或 0.0.0.0:8080,而不是 127.0.0.1:8080。
launch.json 里配 port 对 TCP 服务无效
很多人在 .vscode/launch.json 里加 "port": 8080,以为这样就能让调试器接管 TCP 端口 —— 不行。port 字段只对 Node.js 的 --inspect 调试协议起作用,跟你的业务 TCP 端口完全无关。
如果你要调试的是 TCP 服务器本身(比如想在 socket.on('data') 里打断点),正确做法只有两种:
- 用
launch模式运行整个脚本,断点打在socket.on回调里,VSCode 会停住并显示chunk内容 - 用
attach模式,先命令行node --inspect=0.0.0.0:9229 server.js,再在 launch.json 里配"address": "localhost", "port": 9229,此时 VSCode 连的是调试协议端口,不是业务端口
混淆这两层端口(业务通信端口 vs V8 调试端口)是远程调试失败最常见的原因。一个负责收包,一个负责传断点信息,它们可以相同也可以不同,但不能指望改一个就影响另一个。

















