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

Electron主进程启动Express服务器遇EADDRINUSE错误求助

Electron主进程启动Express报EADDRINUSE但端口未被占用的解决方案

问题详情

启动Electron主进程中的Express服务器时,出现如下报错:

Uncaught Error: listen EADDRINUSE: address already in use :::33333
    at __node_internal_captureLargerStackTrace (node:internal/errors:490:5)
    at __node_internal_uvExceptionWithHostPort (node:internal/errors:589:12)
    at Server.setupListenHandle [as _listen2] (node:net:1740:16)
    at listenInCluster (node:net:1788:12)
    at Server.listen (node:net:1876:7)
    at Function.listen (C:\Users\johndoe\stuff\node_modules\express\lib\application.js:635:24)
    at main.js:18:10

当前使用的main.js代码:

// Modules to control application life and create native browser window
const { app, BrowserWindow, ipcMain, dialog} = require('electron')
const path = require('path');
const { electron } = require('process');
const $ = require('jquery');
const fs = require('fs');
const { Console } = require('console');

const express = require("express")
const expresso = express();
const port = 33333;

expresso.get('/invokeFunction', (req, res) => {
  myFunction(); // this is the function you want to invoke
  res.send('Function invoked!');
});

expresso.listen(port, () => {
  console.log(`Server listening at http://localhost:${port}`);
});

function myFunction() {
  console.log("Function in Electron's main.js has been triggered.");
}

Python调用代码:

# testing communication between processes
import requests

response = requests.get('http://localhost:33333/invokeFunction')

已通过netstat确认端口33333未被占用,程序停止时连接已关闭,但问题仍存在。


可能原因及解决方案

1. Electron进程重启时,旧Express服务器未正确关闭

开发模式下(如使用热重载),Electron实例重启时,旧进程可能未彻底终止,导致残留的Express服务器仍占用端口。

解决方法:
保存Express服务器实例,在Electron退出时主动关闭:

const express = require("express")
const expresso = express();
const port = 33333;
let server; // 保存服务器实例

expresso.get('/invokeFunction', (req, res) => {
  myFunction();
  res.send('Function invoked!');
});

// 仅在app就绪后启动服务器,避免重复执行
app.whenReady().then(() => {
  server = expresso.listen(port, () => {
    console.log(`Server listening at http://localhost:${port}`);
  });
});

// 监听app退出事件,关闭服务器
app.on('quit', () => {
  if (server) {
    server.close(() => {
      console.log('Express server closed');
    });
  }
});

// 处理所有窗口关闭的逻辑
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

2. 代码重复执行导致多次调用listen

原代码在全局作用域直接调用expresso.listen(),Electron启动流程或热重载可能导致这段代码被多次执行,重复绑定端口。

解决方法:
将服务器启动逻辑放入app.whenReady()回调内,确保仅执行一次(如上述代码所示)。

3. IPv6端口占用未被netstat检测到

报错显示端口绑定的是:::33333(IPv6地址),若netstat仅检查了IPv4端口,可能遗漏IPv6的占用情况。

解决方法:
指定绑定IPv4地址127.0.0.1,避免IPv6端口冲突:

// 修改listen的地址参数
server = expresso.listen(port, '127.0.0.1', () => {
  console.log(`Server listening at http://127.0.0.1:${port}`);
});

同时修改Python调用代码的地址:

response = requests.get('http://127.0.0.1:33333/invokeFunction')

4. 手动清理残留Electron进程

若上述方法无效,可能存在未彻底退出的Electron进程,手动杀死所有相关进程:

  • Windows:打开任务管理器,结束所有electron.exe进程
  • macOS/Linux:执行终端命令 killall electron

内容的提问来源于stack exchange,提问作者Justin Ridenour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:54:55