排查 Windows 动态端口与保留端口冲突
我启动 Cocos CLI 时遇到了这个错误:
listen EACCES: permission denied 0.0.0.0:92309230 没有被其他进程监听,问题是它落进了 Windows 的 TCP 排除范围。继续检查后,我又发现系统的 TCP 动态端口被旧配置改成了 1024-15000。
先看端口有没有被占用
Get-NetTCPConnection -LocalPort 9230 -ErrorAction SilentlyContinue |
Format-Table LocalAddress,LocalPort,State,OwningProcess有结果时,根据 PID 查进程:
Get-Process -Id <PID>端口占用通常对应 EADDRINUSE。我这次没有监听进程,Node.js 返回的是 EACCES,所以继续检查系统保留范围。
查看动态端口和排除端口
netsh interface ipv4 show dynamicportrange protocol=tcp
netsh interface ipv6 show dynamicportrange protocol=tcp
netsh interface ipv4 show excludedportrange protocol=tcp
netsh interface ipv6 show excludedportrange protocol=tcp现代 Windows 默认的 TCP 动态端口范围是:
Start Port : 49152
Number of Ports : 16384我的机器显示为:
Start Port : 1024
Number of Ports : 13977也就是 1024-15000。排除列表中还有一个覆盖 9230 的区间,因此这个端口没有进程占用,应用仍然无法监听。
检查 MaxUserPort
Get-ItemProperty `
-LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' `
-Name MaxUserPort `
-ErrorAction SilentlyContinue我这里的值正好是 15000,与异常动态范围的上界一致。这个旧参数把 TCP 动态端口压到了开发服务常用的低位区域。
不能仅凭这一项判断是谁写入了配置。我检查时机器上同时有 Hyper-V、HNS、WinNAT 和 WSL,它们会使用排除端口,但没有证据说明其中某一个修改了 MaxUserPort。这也不是中病毒的证据。
删除旧配置并重启
先记下原值,然后在管理员 PowerShell 中执行:
Remove-ItemProperty `
-LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' `
-Name MaxUserPort
Restart-Computer我没有逐段删除排除端口。那些范围可能由 HNS、WSL 或 Hyper-V 重新创建,强行删除还可能影响它们的网络。
重启后再次检查:
netsh interface ipv4 show dynamicportrange protocol=tcp
netsh interface ipv6 show dynamicportrange protocol=tcpIPv4 和 IPv6 TCP 应当恢复为 49152 起始、16384 个端口。最后直接测试 9230 能否监听:
node -e "const s=require('net').createServer();s.listen(9230,'0.0.0.0',()=>{console.log('bind OK');s.close()})"看到 bind OK 后,再启动原来的开发服务。
如果需要恢复修改前的值,可以写回并重启:
New-ItemProperty `
-LiteralPath 'HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters' `
-Name MaxUserPort `
-PropertyType DWord `
-Value 15000 `
-Force
Restart-Computer这里的 15000 是我机器上的旧值,不是推荐值。其他机器应该使用自己事先记录的值。