不知从什么时候开始,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 Ports0 - 1023
User Ports1024 - 49151
Dynamic Ports49152-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:
TIM图片20200303215932.png

而我的动态端口范围:
Snipaste_2020-03-03_22-02-21.png

原因就很显而易见了,在某一次KB更新中微软重新把动态端口的范围改为了 1024+,原因不明;而后 hyper-v 理所当然的“保留”了“没有人占用的”动态端口中的几段,悲剧就这么发生了……

(hyper-v:我寻思着没人要……)

知道了原因,按照上文那篇微软的文章就可以重新设定动态端口范围来解决这个问题了:

PS C:\Windows\system32> netsh int ip set dynamicport tcp start=49152 num=16384
确定。

重启解决

太坑了…………

标签: none

已有 5 条评论

  1. woaiwinnie2 woaiwinnie2

    几年前碰到这个问题,把端口号改到了10800,然后今年10800也不行了,两月份查到是hyperV的问题关掉了hyperV,现在终于有一劳永逸的解决方法了……

    1. syf syf

      相当坑的问题,难以排查

  2. qrqhuang qrqhuang

    之前看到过该issue, 然后在楼主这得到了科普, 感谢。

  3. syf syf

    net stop winnat
    net start winnat

添加新评论