标签归档:Hyper-V

程序无法监听端口,但端口未被占用

之前写过一个情况,是由于程序权限不足而导致无法监听小端口号,但是今天我又遇到一个奇怪的情况。

调试node.js后端的时候需要监听3000端口,前几天都是好的,但是刚才启动的时候报了bind EACCES 错误,查看端口并没有被使用,程序在别的电脑上就正常。整来整去还是不行,于是开始在网上找有没有类似的情况,竟然让我找到了。

在一个搜索结果里出现列Hyper-V字样立刻吸引了我的注意,因为我昨天由于一些软件无法启动,排查问题的时候打开了Windows Sandbox,这是微软基于Hyper-V做的windows沙盒。

看了看内容应该大差不差找到原因了,启用Hyper-V会导致系统保留一些端口,这些端口不能被别的程序使用,而我用的3000正好在里面,于是就出现了今天这种端口明明没有被别的程序使用,但就是不能监听的情况。

解决方法原文在这里

简单描述一下就是在启用Hyper-V之前要用netsh设置一下你需要的端口列表,确保启用Hyper-V之后这些端口不会被保留。

netsh int ipv4 add excludedportrange protocol=tcp startport=3000 numberofports=1

然后再启用Hyper-V就可以了。

要注意的是在Hyper-V或者Sandbox启用的情况下进行设置不会直接生效,必须先禁用再启用才行。

相关资料:

2022/3/1 更新

今天发现一个更方便的方法,不需要先关闭hyper-v服务再开,方案在这里

首先重新分配一个端口段,只要我们需要监听的端口不在里面即可


netsh int ipv4 set dynamicport tcp start=49152 num=16384

然后编辑注册表禁用端口排除(但是使用netsh int ipv4 show excludedportrange protocol=tcp 可以看到还是有排除的端口,只不过变成了前一条命令设置的范围)


reg add HKLM\SYSTEM\CurrentControlSet\Services\hns\State /v EnableExcludedPortRange /d 0 /f

然后重启

重要提示:设置排除端口时你必须设置足够多的端口(几千到几万个)才能保证需要对外发起连接的程序能正常工作,因为发起连接需要占用一个端口,如果你设置的排除端口不够多,那么端口资源很快就会被耗尽,之后发起的连接就会出现addr in use之类的报错。