先確認錯誤涉及哪個監聽連接埠

Clash 啟動時出現連接埠遭占用的提示,通常是內核建立本機監聽器時發生問題。日誌中的 bind: address already in use 表示無法依目前設定繫結目標位址與連接埠;Windows 也可能顯示 Only one usage of each socket address。這類錯誤與訂閱是否過期、節點是否連得上無關,先更換節點通常無法解決。

mixed-port 會在同一個連接埠接受 HTTP 與 SOCKS 代理連線。本文以 7890 為舊連接埠、17890 為新連接埠示範,兩者都只是範例,不能據此認定本機一定使用 7890,或 17890 一定未被占用。請先開啟用戶端日誌,記下錯誤行中的位址、連接埠與通訊協定。

欄位用途處理方式
mixed-portHTTP 與 SOCKS 共用的代理入口變更後同步更新系統代理與應用程式代理
port / socks-port獨立的 HTTP / SOCKS 入口檢查是否與混合入口重複設定
external-controller用戶端連線至內核的控制介面一併調整用戶端的控制介面設定
dns.listen內核 DNS 服務的監聽位址依日誌中的 DNS 連接埠個別排查

Windows:找出占用 7890 的程序及其啟動來源

使用 PowerShell 查詢監聽 PID

開啟 PowerShell,先執行下方查詢。OwningProcess 是占用連接埠的程序 ID,不是程式名稱。如果遇到存取權限限制,再以系統管理員身分開啟終端機;不要為了方便直接結束不明的系統程序。

Get-NetTCPConnection -LocalPort 7890 -State Listen |
  Select-Object LocalAddress, LocalPort, State, OwningProcess

假設查詢結果中的 PID 是 1234,接著查看程序名稱、可執行檔路徑與啟動命令。以下數字僅用來示範查詢方式,實際操作時請換成上一個指令回傳的 PID。

Get-Process -Id 1234 |
  Select-Object Id, ProcessName, Path

Get-CimInstance Win32_Process -Filter "ProcessId = 1234" |
  Select-Object ProcessId, ExecutablePath, CommandLine

路徑與啟動參數有助於分辨兩種情況:另一個用戶端啟動了獨立內核,或同一個用戶端的背景服務仍在執行。即使程序名稱都是 mihomo.exe,也可能來自不同的安裝目錄。關閉工作列視窗不代表程序已結束,請先從系統匣選單正常退出對應的用戶端,再重新查詢連接埠。

使用 netstat 交叉確認

netstat -ano -p tcp | findstr ":7890"
tasklist /FI "PID eq 1234"

findstr 只是文字篩選工具,也可能比對到遠端連接埠或包含相同數字的其他連接埠。請確認「本機位址」欄是否確實以 :7890 結尾,以及狀態是否為 LISTENING。一般的 ESTABLISHED 連線不能直接證明本機有 7890 代理正在監聽。

  • 127.0.0.1:7890:IPv4 回送位址監聽。
  • 0.0.0.0:7890:IPv4 通用位址監聽,可能與回送位址上的繫結衝突。
  • [::]:7890:IPv6 通用位址監聽,是否同時影響 IPv4 取決於通訊端設定。

如果日誌明確指出 UDP 繫結失敗,再查詢 UDP 端點。UDP 沒有 TCP 的 LISTENING 狀態,不能沿用只篩選 TCP 監聽的判斷方式。

Get-NetUDPEndpoint -LocalPort 7890 |
  Select-Object LocalAddress, LocalPort, OwningProcess

macOS 與 Linux:檢查監聽程序和背景服務

macOS:使用 lsof

在「終端機」執行下方指令。-nP 會保留數字位址與連接埠,避免名稱解析影響判讀;-sTCP:LISTEN 只顯示監聽中的通訊端。若權限不足或結果不完整,可在指令前加上 sudo。

lsof -nP -iTCP:7890 -sTCP:LISTEN
ps -p 1234 -o pid,ppid,command

查看 COMMAND、PID 與完整啟動命令後,從對應的用戶端選單正常退出。如果程序立刻重新出現,可能是由登入項目、用戶端背景元件或服務管理器管理。請先停用對應的啟動來源,再結束程序;反覆強制結束只會讓監督程序不斷重新啟動內核。

Linux:使用 ss

sudo ss -ltnp 'sport = :7890'
sudo ss -lunp 'sport = :7890'
ps -p 1234 -o pid,ppid,args

第一個指令查詢 TCP 監聽,第二個查詢 UDP 繫結。ss 通常由發行版提供的 iproute2 套件安裝;若未安裝,可用已安裝的 lsof 查詢。完整顯示程序資訊可能需要系統管理員權限。

如果內核是透過 systemd 啟動,請檢查實際的服務單元及其 ExecStart。只關閉桌面用戶端可能不會停止服務。也請留意 Docker 的連接埠發布設定:主機上的 7890 可能由容器占用,不要只檢查目前登入使用者啟動的程式。處理原則都是先確認程序歸屬,再透過原本的管理方式停止它。

選擇釋放舊連接埠,或變更 mixed-port

找出占用程序後,不必立刻結束它。先判斷是否需要讓它繼續執行。如果是舊用戶端或重複啟動的內核,退出多餘的執行個體、保留一個即可。如果占用者是仍在使用的其他服務,變更 Clash 的代理入口通常比中斷該服務更合適。

  1. 記下目前使用的連接埠、系統代理位址,以及應用程式個別設定的代理位址。
  2. 查詢候選連接埠 17890,方法與查詢 7890 相同。
  3. 確認要保留的用戶端與內核執行個體,避免同時修改兩份設定。
  4. 修改實際生效的設定來源,然後重新載入或重新啟動內核。
  5. 確認新連接埠已開始監聽,再更新系統與應用程式使用的連接埠。

在 YAML 與用戶端設定中變更 mixed-port

直接管理設定檔

請先備份設定檔,再於 YAML 頂層找到既有的 mixed-port 並修改,不要在檔案結尾另加同名欄位。下方只展示與代理入口相關的設定片段,請合併到現有的完整設定中,保留原有節點、策略群組、DNS 與規則。

# 合併到現有設定,不是完整的訂閱檔案
mixed-port: 17890
allow-lan: false
bind-address: "127.0.0.1"

此範例適用於僅供本機使用的情境。如果原本使用區域網路共用代理,不要直接照搬存取範圍設定;請另外核對監聽位址、驗證方式與防火牆規則。不要為了解決本機連接埠衝突而順便開放區域網路存取,這樣並不能釋放已被占用的連接埠。

也請檢查是否有 port: 17890 或 socks-port: 17890。獨立入口與混合入口不應重複繫結相同的位址與 TCP 連接埠。如果只使用混合入口,請先確認用戶端不依賴獨立入口,再移除相應的獨立連接埠欄位,或依內核設定規範設為 0 以停用。

手動執行 mihomo 時,可在終端機檢查設定。以下假設目前目錄中的實際檔名為 config.yaml,內核指令為 mihomo。

mihomo -t -f config.yaml

-t 用於測試設定,不代表代理監聽已成功建立。測試完成後,仍需透過正常的啟動方式載入檔案並查看啟動日誌。用戶端自行下載或產生的執行設定可能與該檔案不同,不能只測試未實際使用的副本。

由圖形介面用戶端管理設定

先檢查用戶端設定中是否有「混合連接埠」、「Mixed Port」或「代理連接埠」欄位。不同用戶端與版本的選單名稱不盡相同,這些名稱是用來辨識欄位,並非統一的選單路徑。修改欄位後請儲存,再依用戶端的要求重新載入內核;只修改訂閱原始內容,不一定能覆寫用戶端產生的連接埠設定。

  • 介面有連接埠設定:優先透過介面修改,再查看執行日誌是否顯示新連接埠。
  • 介面沒有對應欄位:確認用戶端是否支援本機覆寫或合併設定,再於其中設定頂層 mixed-port。
  • 更新訂閱後又變回 7890:檢查是否直接編輯了會遭覆寫的訂閱快取,並將修改移到用戶端支援的持續性設定位置。
  • 儲存後仍監聽舊連接埠:核對目前選取的設定、執行檔路徑與用戶端設定優先順序,再重新啟動正確的內核執行個體。

修改前可先關閉系統代理,避免系統持續連線至暫時不存在的監聽器。新連接埠成功啟動後再重新啟用。如果用戶端會自動設定系統代理,也請前往系統設定確認最後的值,不要假設已自動同步。

將系統代理、瀏覽器與命令列工具同步至新連接埠

內核改用 17890 後,系統仍連線至 7890,是「連接埠衝突已排除,網頁卻仍無法開啟」的常見原因。本機 HTTP 代理的目標應改為 127.0.0.1:17890。混合連接埠也接受 SOCKS 連線,但仍須依照應用程式要求的代理類型與格式填寫。

位置檢查路徑或方式新值範例
Windows 11「設定」→「網路和網際網路」→「Proxy」→「手動設定 Proxy」→「編輯」位址 127.0.0.1,連接埠 17890
近期版本的 macOS「系統設定」→「網路」→目前網路的「詳細資訊」→「代理伺服器」確認網頁代理與安全網頁代理的位址和連接埠
Firefox 個別代理設定「設定」→「一般」→「網路設定」→「設定」使用系統代理,或更新手動代理的連接埠
命令列程式檢查 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY 及工具本身的設定改用新連接埠,必要時開啟新的終端機

Linux 桌面環境沒有統一的系統代理選單,GNOME、KDE 與各個應用程式可能各自管理設定。Windows 系統代理與 WinHTTP 代理也不是同一套設定,可使用 netsh winhttp show proxy 單獨查看後者;不要把重設 WinHTTP 當成所有瀏覽器問題的通用解法。

下方的 PowerShell 指令只會更新目前工作階段的 HTTP 代理環境變數,不會變更所有應用程式的設定。透過本機 HTTP 代理建立 HTTPS 目標的通道時,代理位址仍可使用 http://;不必因為目標是 HTTPS,就把本機入口改成 TLS。

$env:HTTP_PROXY = "http://127.0.0.1:17890"
$env:HTTPS_PROXY = "http://127.0.0.1:17890"

macOS 與 Linux 的 shell 可暫時設定:

export http_proxy=http://127.0.0.1:17890
export https_proxy=http://127.0.0.1:17890

如果先前設定過 ALL_PROXY、Git 的 http.proxy 或編輯器內建代理,也需要個別核對。各工具讀取變數的方式不同;修改環境變數後,已執行中的應用程式通常不會自動取得新值。

透過監聽、請求與重新啟動完成驗收

先確認本機監聽,再測試請求

重新執行前文的連接埠查詢,將 7890 改為 17890,並確認監聽者是預計使用的內核。接著使用明確指定代理的參數發出請求,排除系統代理設定是否生效的不確定性。Windows 請使用 curl.exe,避免部分 PowerShell 環境中的同名別名影響參數解讀。

# Windows
curl.exe --noproxy "" --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 15 -I https://example.com

# macOS / Linux
curl --noproxy "" --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 15 -I https://example.com

此處的 5 秒是連線逾時上限,15 秒是整個請求的時間上限,並非效能測量結果。--noproxy "" 用來清除本次請求的代理略過清單;回應結果仍會受到節點、規則、DNS 與目標網站狀態影響。

  • 立即顯示連線遭拒:優先確認新連接埠是否正在監聽、位址是否正確,以及內核是否已退出。
  • 已連上本機入口,但請求逾時:接著檢查內核日誌中的節點連線、規則比對與 DNS 錯誤。
  • 明確指定代理的請求成功,瀏覽器卻失敗:優先檢查瀏覽器個別代理、系統代理中的舊連接埠與擴充功能設定。
  • 命令列請求成功,但流量未經預期節點:檢查實際套用的規則與策略選擇;請求成功本身不代表流量經過代理節點。

最後檢查重新啟動與更新訂閱

退出並重新啟動用戶端,確認仍在監聽 17890。接著依平常方式更新一次訂閱,確認連接埠沒有恢復為 7890。如果重新啟動後連接埠再次遭占用,請檢查其他用戶端的開機啟動項目與背景服務,不要每次都臨時改用另一個數字。

TUN 模式也要分開判斷:TUN 接管的是系統網路流量,不代表應用程式一定會經過 mixed-port。啟用 TUN 後網頁可以開啟,不能證明舊的系統代理連接埠已修正;部分用戶端也可能因混合入口衝突而無法啟動某些功能。驗收時仍須分別確認日誌、本機監聽與請求流向。