如何彻底终止Node.js TCP服务器并在同一进程中重启
解决Node.js TCP服务器重启时的EADDRINUSE错误
这个问题我之前也踩过坑!核心原因是TCP协议的TIME_WAIT状态,不是你的代码写法有问题,而是操作系统的网络机制在起作用。
当你调用server.close()后,服务器确实停止了监听,但底层的TCP套接字并不会立刻释放端口——它会进入TIME_WAIT状态(通常持续1-2分钟),这是TCP协议的设计,用来确保网络中残留的数据包被正确处理,避免出现数据混乱。在这个状态下,操作系统默认不允许其他进程(甚至同一进程的新服务器)绑定同一个端口,所以你才会看到EADDRINUSE错误。
解决方案:启用reuseAddr选项
Node.js的net.createServer()和server.listen()支持reuseAddr配置,开启这个选项后,允许套接字绑定到处于TIME_WAIT状态的端口上。
修改你的代码如下:
const net = require('net'); // 启动第一个服务器 const server = net.createServer(); server.listen(9876, 'localhost', () => { console.log('第一个服务器已启动在9876端口'); // 关闭第一个服务器 server.close(() => { console.log('第一个服务器已关闭'); // 启动第二个服务器,启用reuseAddr const anotherServer = net.createServer(); anotherServer.listen({ port: 9876, host: 'localhost', reuseAddr: true // 关键配置 }, () => { console.log('第二个服务器已重启在9876端口'); // 关闭第二个服务器 anotherServer.close(() => { console.log('第二个服务器已关闭'); }); }); }); });
补充说明
reuseAddr的作用:允许同一端口被多个套接字绑定(只要所有绑定的套接字都开启了这个选项),对于TCP场景,它直接绕过了TIME_WAIT的端口占用限制,非常适合测试环境中的热重载/重启需求。- 测试环境备选方案:如果不需要固定端口,可以使用
port: 0让操作系统自动分配可用端口,这样完全避免端口冲突问题,比如:anotherServer.listen({ port: 0, host: 'localhost' }, () => { console.log(`服务器启动在端口 ${anotherServer.address().port}`); });
内容的提问来源于stack exchange,提问作者navelencia
相关产品推荐
相关产品推荐

