The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

Windows 10 無法 LISTEN Port 4200 與 Port 3000 的靈異事件整理

前陣子我的 Windows 10 (版本 1809) 電腦發生了一個靈異事件,就是電腦突然無法 LISTEN 常用的 4200 與 3000 通訊埠,我想盡腦汁也想不出為什麼無法 LISTEN,超出了我的認知範圍,雖然最後已經找到解決辦法,但還是有些疑惑尚未釐清。我就用這篇文章整理一下我遭遇的狀況!

問題說明

我常用的 Angular CLI 會在啟動開發伺服器時使用 4200 Port,而 lite-server 則預設採用 3000 Port,以及 .NET Core CLI 則是 5000 與 5001 Port,這幾年來從來也沒有出問題過,但就某一天,有個 Port 3000 不能用了,嘗試重開機後,變成 Port 4200 不能用了,實在超詭異 !

由於我當時不能用的通訊埠是 Port 3000,以下是我的偵查過程:

  1. 先用 netstat -nat | findstr 3000 查出 Port 3000 的使用情形

    image

    從上圖可以看出我的電腦沒有任何應用程式正在使用 Port 3000 通訊埠,但就是被不明原因占用,不知道是被誰用掉的。

  2. 使用 TCPView 查看通訊埠使用情況

    這裡一樣沒有任何使用 Port 3000 的任何應用程式。

  3. 開啟資源監視器查看所有接聽連接埠

    一樣沒有任何使用 Port 3000 的活動!

  4. 使用 CurrPorts 查看通訊埠使用情況

    一樣沒有任何使用 Port 3000 的活動!

照理來說 netstat 已經足以看出電腦的網路連線狀況,但這實在超出我能理解的範圍,總之沒有應用程式正在使用 Port 3000,怎麼這個 Port 就是無法使用呢?我還換了各種不同的工具嘗試去 LISTEN 3000 Port 也都失敗,像是:

  1. netcat

    nc -L -p 3000
    
    Can't grab 0.0.0.0:3417 with bind
    
  2. live-server

    live-server --port=3000
    
    Error: listen EACCES 0.0.0.0:3417
    
  3. .NET Core CLI

    SET ASPNETCORE_URLS=https://*:3000 && dotnet run --no-launch-profile
    
    crit: Microsoft.AspNetCore.Server.Kestrel[0]
          Unable to start Kestrel.
    System.Net.Sockets.SocketException (10013): 嘗試存取通訊端被拒絕,因為存取權限不足。
    

追查過程

這些工具通通遇到無法 LISTEN 的錯誤,所以我最後就直接推斷,應該是作業系統造成的!

我從 Port are blocked after you install February 13 cumulative update 4074588 in Windows 10 Version 1709 這篇文章找到一點蛛絲馬跡,發現了以下命令,這個命令可以列出所有被作業系統排除的通訊埠(Ports)清單:

netsh int ipv4 show excludedportrange protocol=tcp

image

這才發現原來我的 Port 3000 不能用,是因為我這台電腦的 Port 2990 ~ 3089 都被不明原因給排除使用範圍,但是被哪個應用程式或系統服務保留卻不得而知,網路上完全沒有文件提到怎樣進一步追查。

最為詭異的地方在於,每次重開機後,有某些範圍的通訊埠會有變化,所以可能這次不能用 3000 Port,重開機後可能變成另一個範圍不能用,完全摸不著頭緒。

然後我試著將 Hyper-V 關閉,也試著將 Docker Desktop 移除,這些保留通訊埠確實少了一點,但每次重開機後,變動的保留通訊埠還是不斷的在 1541 ~ 10000 之間跳動,讓人覺得非常不安。

dism.exe /Online /Disable-Feature:Microsoft-Hyper-V

解決方案

在進一步研究後發現,其實有兩種解決方法:

  1. 重啟 winnat 服務即可釋放所有被鎖定的 Port Range

    # 1. 停用 WSL 服務
    wsl --shutdown
    wsl -l -v
    
    # 2. 停用 Docker 服務
    
    # 3. 重啟 WinNAT 服務
    net stop winnat
    net start winnat
    
    # 4. 啟動 Docker 服務
    
    # 5. 如果發現網路出現問題,那還是用「重開治百病」這招吧!
    

    參考來源: https://superuser.com/a/1610009 & https://github.com/docker/for-win/issues/3171#issuecomment-739740248

  2. 設定自己專用的保留通訊埠

    原來 Windows 10 使用者可以設定自己專用的保留通訊埠,所以我決定把常用的通訊埠固定下來,這樣就沒有人可以用我會用到的通訊埠了!

    netsh int ipv4 add excludedportrange protocol=tcp numberofports=1 startport=3000
    netsh int ipv4 add excludedportrange protocol=tcp numberofports=1 startport=3001
    netsh int ipv4 add excludedportrange protocol=tcp numberofports=1 startport=4200
    netsh int ipv4 add excludedportrange protocol=tcp numberofports=1 startport=5000
    netsh int ipv4 add excludedportrange protocol=tcp numberofports=1 startport=5001
    netsh int ipv4 add excludedportrange protocol=tcp numberofports=1 startport=8080
    netsh int ipv4 add excludedportrange protocol=tcp numberofports=1 startport=8888
    

    如果要刪除自訂的保留通訊埠,可以用以下命令:

    netsh int ipv4 delete excludedportrange protocol=tcp numberofports=1 startport=3000
    netsh int ipv4 delete excludedportrange protocol=tcp numberofports=1 startport=3001
    netsh int ipv4 delete excludedportrange protocol=tcp numberofports=1 startport=4200
    netsh int ipv4 delete excludedportrange protocol=tcp numberofports=1 startport=5000
    netsh int ipv4 delete excludedportrange protocol=tcp numberofports=1 startport=5001
    netsh int ipv4 delete excludedportrange protocol=tcp numberofports=1 startport=8080
    netsh int ipv4 delete excludedportrange protocol=tcp numberofports=1 startport=8888
    

相關連結

留言評論