Win10 各種端口占用問題的解決辦法
在啟用 Hyper-V 後,總是會產生各種埠被佔用的問題
我遇到過的問題就有:
-
啟動 IDEA 時,報錯:
java.net.BindException: Address already in use: bind
-
使用 Clash for Windows 時,Could not connect to Clash Core,日誌:
time="2020-07-28T07:08:37+08:00" level=error msg="External controller error: listen tcp 127.0.0.1:9090: bind: An attempt was made to access a socket in a way forbidden by its access permissions."
顯然,這兩個錯誤都是埠被佔用造成的。
根據IDEA Start Failed: Address already in use - Serge Baranov 的回答,IDEA 會在 6942~6991 中尋找一個埠並 bind。由此可見,錯誤原因是這 50 個埠都已經被佔用。
根據日誌內容,第二個問題是 9090 埠被佔用造成的
對於一般的端口占用問題,比如我的 27891 被佔用,可以先查找出正在使用此埠的程序,再強行終止這個程序(如果失敗可以試試以管理員身份):
PS C:\Users\hyuuko> netstat -ano | findstr 27891 TCP 127.0.0.1:8780 127.0.0.1:27891 SYN_SENT 6276 TCP 127.0.0.1:8802 127.0.0.1:27891 SYN_SENT 6276 PS C:\Users\hyuuko> taskkill /pid 6276 /F 成功: 已終止 PID 為 6276 的程序。 PS C:\Users\hyuuko>
然而,我使用netstat -ano | findstr 埠號
命令時,發現 6942~6991 和 9090 並未被某個程序使用。這說明這些埠可能是被系統保留了,比如 Hyper-V。
根據List of TCP and UDP port numbers - Wikipedia所言,tcp/udp 埠號被分為 3 段:
埠型別 | 範圍 | 用途 |
---|---|---|
周知埠 | 0 - 1023 | 提供廣泛使用的網路服務型別的系統程序使用 |
註冊埠 | 1024 - 49151 | 給使用者程序或應用程式使用,比如 IDEA |
動態埠 | 49152-65535 | 用於私有或定製服務、臨時目的以及臨時埠的自動分配 |
Hyper-V 會將動態埠中的幾段範圍的埠保留給自己使用,使用者的應用程式無法使用這些埠。從 Windows Vista 和 Windows Server 2008 起,Windows 將 49152-65535 劃分為 動態埠,見
# 檢視tcp ipv4動態埠範圍
PS C:\Users\hyuuko> netsh int ipv4 show dynamicport tcp
協議 tcp 動態埠範圍
---------------------------------
啟動埠 : 1024
埠數 : 13977
# 檢視tcp ipv4埠排除範圍(被系統或者我們自己保留的埠)
PS C:\Users\hyuuko> netsh int ipv4 show excludedport tcp
協議 tcp 埠排除範圍
開始埠 結束埠
---------- --------
1578 1677
1678 1777
太多了這裡省略...
8974 9073
9074 9173
9174 9273
太多了這裡省略...
11301 11400
11401 11500
50000 50059 *
* - 管理的埠排除。
PS C:\Users\hyuuko>
可以看到,9074~9173 等等範圍內的埠被系統保留了(絕對是 Hyper-V 乾的!),導致 clash 不能使用 9090 埠。現在知道原因了,有三種解決辦法(我用的第二種)
第一種解決辦法(不推薦)
更改 clash 使用的埠,將 9090 改成較高的 29091,可是治標不治本,因為 Hyper-V 下次可能就會將 29091 保留給自己用。再者而這還不能解決 IDEA 的問題,你不能改變 IDEA 想要使用的埠。
第二種解決辦法
先以管理員身份開啟 powershell,然後設定 tcp ipv4 的動態埠範圍為 49152 開始的 16384 個埠,也就是 49152~65535
netsh int ipv4 set dynamicport tcp start=49152 num=16384
然後重啟電腦。Hyper-V 就會從 49152~65535 範圍內保留一部分埠,6942~6991 和 9090 不受影響。
檢視一下此時的動態埠範圍:
PS C:\Users\hyuuko> netsh int ipv4 show dynamicport tcp
協議 tcp 動態埠範圍
---------------------------------
啟動埠 : 49152
埠數 : 16384
第三種解決辦法
先以管理員身份開啟 powershell,然後將 9090 等埠設定為排除埠給應用程式使用。
# 保留 6942~6951 這10個埠給應用程式使用
netsh int ipv4 add excludedportrange protocol=tcp startport=6942 numberofports=10
# 保留 9090 埠給應用程式使用
netsh int ipv4 add excludedportrange protocol=tcp startport=9090 numberofports=1
然後重啟電腦。因為 9090 等埠被保留給應用程式使用了,Hyper-V 就無法將 9090 保留給自己使用了。
檢視一下此時被保留的埠:
PS C:\Users\hyuuko> netsh int ipv4 show excludedport tcp
協議 tcp 埠排除範圍
開始埠 結束埠
---------- --------
1578 1677
1678 1777
太多了這裡省略...
9090 9090 *
太多了這裡省略...
11301 11400
11401 11500
太多了這裡省略...
* - 管理的埠排除。
帶星號的就是被管理員保留的埠,可以被應用程式使用
如果要取消保留埠,可以:
netsh int ipv4 delete excludedportrange protocol=tcp startport=9090 numberofports=1