You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何彻底终止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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:02:39