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
相关产品推荐
相关产品推荐

