Dynamic Port Range 端口保留问题
不知从什么时候开始,shadowsocks 开启后一直无法监听 1080 端口,当时换了 1081、1082 也不行,于是换了个比较高的 10800 端口解决了,也没当回事。今天因为要跑一个非 maven 的项目,需要在 idea 里手动配置 tomcat,默认的 JMX 端口 1099 又没法分配,而使用netstat -ano | grep "1099"
又显示没有任何程序在占用这个端口,非常诡异。后来更改为 1098、1097 也是和上次 shadowsocks 同样的情况,死活绑定不上去,而 netstat 又显示没有程序占用这个端口,换成比较高的比如 11099 又可用了……
经过二分法尝试发现,1060~1777 这段端口全部都无法绑定
Google 之后发现了这个issue,这是 hyper-v 设置的保留端口……
PS C:\Windows\system32> netsh int ip show excludedportrange protocol=tcp
协议 tcp 端口排除范围
开始端口 结束端口
---------- --------
1060 1159
1160 1259
1260 1359
1360 1459
1460 1559
1560 1659
1678 1777
2180 2279
2869 2869
5357 5357
10243 10243
50000 50059 *
* - 管理的端口排除。
可以看见 hyper-v 保留了大量 3000 以下常用的端口段,好坑啊,这些保留端口通过 netstat 查看都是显示没有程序占用的,但是程序想绑定它们又绑定不了,造成一种“端口已被其他程序绑定”的错觉,不管你怎么百度Google,都无从下手……记得以前计算机网络课上好像讲过一般 1024 以下的端口是保留的,都是有比较常见古老的程序绑定,比如ssh监听22,telnet监听23之类的。一开始还在想是哪个服务会保留这么多常用的端口范围,哎。
这个问题去年就已经出现了,好多网友因为被占用一大堆端口而无法使用 skype、idea 之类需要绑定端口通讯的程序。那么 hyper-v 为什么会占用这么多常用端口呢?
基于不同的用途,tcp/ip 端口号分为 3 段:
名称 | 范围 |
---|---|
System Ports | 0 - 1023 |
User Ports | 1024 - 49151 |
Dynamic Ports | 49152-65535 |
这个端口范围的划分是由 IANA(Internet Assigned Numbers Authority,互联网号码分配局)划分的,详细划分依据可以参考 这篇文章。大致的划分依据就是0~1023是大部分server端程序端口,比如 http,ssh,smtp;1024~49151 是用户程序,例如我在上文中使用到的 JMX、代理服务,和很多网友提到的 skype for business、IDEA;而最后一段 Dynamic Ports,顾名思义就是 hyper-v 本身“想”用来保留的动态端口。更详细的端口列表可以看 这篇维基
从 Windows Vista / Server 2008 起,微软就严格遵循这个标准,把默认的 Dynamic Ports 范围设置为 49152~65535。
为了验证这个说法,我请朋友帮忙验证了他的机器上 Dynamic Ports 的范围,他的 Windows 版本号是 10.0.15063:
而我的动态端口范围:
原因就很显而易见了,在某一次KB更新中微软重新把动态端口的范围改为了 1024+,原因不明;而后 hyper-v 理所当然的“保留”了“没有人占用的”动态端口中的几段,悲剧就这么发生了……
(hyper-v:我寻思着没人要……)
知道了原因,按照上文那篇微软的文章就可以重新设定动态端口范围来解决这个问题了:
PS C:\Windows\system32> netsh int ip set dynamicport tcp start=49152 num=16384
确定。
重启解决
太坑了…………
几年前碰到这个问题,把端口号改到了10800,然后今年10800也不行了,两月份查到是hyperV的问题关掉了hyperV,现在终于有一劳永逸的解决方法了……
相当坑的问题,难以排查
之前看到过该issue, 然后在楼主这得到了科普, 感谢。
很高兴能帮到你
net stop winnat
net start winnat