錯誤訊息說明了什麼
Clash 系客戶端(包括基於 mihomo 核心的各類圖形介面)啟動時會嘗試監聽一組本機埠,用於接收系統或瀏覽器發來的代理請求。最常見的一個是混合埠 7890(mixed-port),它同時接受 HTTP 與 SOCKS5 兩種協議的連線。如果這個埠已經被另一個程式占用,核心會在日誌裡拋出類似下面的錯誤並直接退出:
FATA[0000] Start Mixin server error: listen tcp 127.0.0.1:7890: bind: address already in use
這條日誌的關鍵是 bind: address already in use——它明確說明問題不在訂閱、不在規則,而是作業系統層面這個埠號已經被占用,新行程無法再繫結同一個埠。常見的還有 7891(部分客戶端的 SOCKS 埠)、9090(外部控制埠 external-controller)、53(DNS 監聽埠)。定位思路完全一致,本文以最常遇到的 7890 為例展開。
埠占用和訂閱失效、節點不可用是兩類完全不同的問題。前者表現為客戶端無法啟動或啟動後立刻退出;後者是客戶端能正常運行,只是連不上目標網站。先看清錯誤發生的階段再排查,能省不少時間。
誰最容易占用 7890
7890 並不是系統保留埠,理論上任何程式都可能搶先占用它,但實際排查中出現頻率最高的幾類情況是:
- 同一台機器上跑了兩個 Clash 類客戶端。比如同時裝了 Clash Verge Rev 和 Clash Plus,又都用預設的 7890,前一個沒退乾淨,後一個自然搶不到埠。
- 上一次行程沒有正常退出。系統休眠、強制結束工作管理員行程、核心崩潰但主程式未清理子行程,都會留下一個殭屍行程繼續占著埠。
- 其他代理工具使用了相同預設埠。部分舊版代理工具、封包擷取工具(如某些設定下的除錯代理)預設也監聽 7890 或相近號段。
- Docker 容器或 WSL2 內部服務做了埠對映,把容器內的服務對映到主機的 7890。
無論是哪一種,處理思路都是先確認占用者是誰,再決定是關閉它還是換個埠給 Clash 用。盲目重開電腦有時能暫時解決,但不清楚成因下次還會復發。
Windows 下用 netstat 定位占用行程
開啟命令提示字元或 PowerShell,執行:
netstat -ano | findstr :7890
正常情況下會輸出類似這樣的一行或多行:
TCP 127.0.0.1:7890 0.0.0.0:0 LISTENING 18420
最後一欄 18420 就是占用該埠的行程 PID。接下來用這個 PID 反查行程名稱:
tasklist | findstr 18420
如果輸出顯示是上一次未退出的客戶端主行程(比如 clash-verge.exe 或 mihomo.exe),說明確實是殘留行程,直接在工作管理員裡手動結束該行程,或執行:
taskkill /PID 18420 /F
結束後重新啟動客戶端即可。如果 PID 對應的是一個陌生程式,先確認它的作用,再考慮關閉該程式或修改 Clash 的監聽埠(見後文)。
不要在不了解行程用途的情況下直接 taskkill。如果查到的 PID 是系統服務或安全軟體,強行結束可能引發其他異常,遇到這種情況優先選擇改埠而不是砍行程。
macOS / Linux 下用 lsof 定位占用行程
macOS 與大多數 Linux 發行版都自帶 lsof(List Open Files),用它查埠比 netstat 更直觀:
lsof -i :7890
輸出範例:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mihomo 22187 alice 7u IPv4 0x1a2b 0t0 TCP 127.0.0.1:7890 (LISTEN)
COMMAND 欄直接給出行程名稱,PID 欄是行程編號。確認是殘留的 Clash 核心行程後,結束它:
kill -9 22187
如果系統沒有 lsof(部分精簡版 Linux 容器),可以用 ss 指令替代:
ss -tlnp | grep 7890
該指令同樣會在末尾給出 pid= 欄位,操作方式與前面一致。Linux 下如果占用埠的是一般使用者權限不足以結束的行程,需要在指令前加 sudo。
方法一:在客戶端介面直接改埠
如果占用 7890 的是一個不方便關閉的常駐程式(比如另一款需要長期運行的工具),更省事的做法是讓 Clash 換一個埠,而不是去動別人。多數圖形客戶端都在設定介面裡提供了埠修改入口,操作路徑通常是:
-
開啟客戶端設定面板
在主介面找到「設定」或齒輪圖示,進入網路 / 埠相關的設定分區,不同客戶端命名略有差異,但都會集中列出混合埠、HTTP 埠、SOCKS 埠等欄位。
-
找到混合埠(Mixed Port)欄位
把原本的
7890改成一個未被占用的埠號,例如17890或7899。建議選擇 1024 以上、10000 以下且不常見的號段,避免再撞上別的軟體。 -
儲存並重啟核心
多數客戶端修改埠後需要點擊「重啟核心」或「套用」按鈕才會生效,單純儲存設定頁可能不會立即重新繫結埠。
-
同步更新系統代理埠
如果客戶端開啟了「設為系統代理」功能,修改混合埠後務必確認系統代理設定裡的埠號也已經同步更新,否則會出現核心正常運行但流量依然連不上的情況。
方法二:直接修改設定檔裡的埠欄位
如果你使用的是手動維護的設定檔,或者客戶端介面暫時無法存取,也可以直接編輯 YAML 設定。找到訂閱設定檔裡下面幾行(欄位名可能因版本而略有差異):
mixed-port: 7890
allow-lan: true
external-controller: 127.0.0.1:9090
把 mixed-port 後面的數值改成一個空閒埠即可,例如:
mixed-port: 17890
如果客戶端同時使用了獨立的 HTTP 埠和 SOCKS 埠(而非統一的 mixed-port),對應欄位通常是:
port: 7890
socks-port: 7891
按需分別修改。注意 external-controller 用的是另一個埠(預設 9090),它是給面板 / 儀表板用的管理介面,和流量轉發埠是兩回事,如果錯誤訊息裡提到的是 9090 被占用,應該改這一行而不是 mixed-port。修改儲存後重啟客戶端或重新載入設定,新埠才會生效。
手動改設定檔後,如果客戶端設為「自動更新訂閱覆蓋本機設定」,下次刷新訂閱時你的埠改動可能被訂閱內容覆蓋回預設值。長期使用的自訂埠建議同時在客戶端介面裡設定一次,兩處保持一致。
修改埠後需要重新檢查的三處
埠號改動後,原來依賴 7890 的一些設定也需要同步調整,否則會出現「客戶端已啟動,但瀏覽不了網頁」的新問題:
- 瀏覽器擴充功能裡的代理埠。如果透過 SwitchyOmega 之類的瀏覽器擴充功能手動設定了代理位址
127.0.0.1:7890,改埠後擴充功能裡的埠號也要同步修改。 - 系統層級代理設定。Windows 的「設定 → 網路和網際網路 → 代理」、macOS 的「系統設定 → 網路 → 代理」裡如果手動填過埠號,同樣要更新。
- TUN 模式不受影響。如果啟用的是 TUN 模式而非系統代理,流量走的是虛擬網卡而非 mixed-port,這種情況下改埠通常不會影響已有的 TUN 設定,但仍建議重啟一次客戶端確認核心完全重新載入。
確認埠已經空閒的驗證方法
結束占用行程或改完埠後,不要憑感覺認為「應該好了」,用指令再確認一次最省心。Windows 下重新執行:
netstat -ano | findstr :7890
如果沒有任何輸出,說明該埠目前處於空閒狀態,可以放心使用。macOS / Linux 下對應執行:
lsof -i :7890
同樣,無輸出即代表埠空閒。之後再啟動 Clash 客戶端,正常情況下日誌裡會出現類似下面的成功提示,而不是之前的 FATA 級錯誤:
INFO[0000] Mixed(http+socks) proxy listening at: 127.0.0.1:7890
看到這一行代表混合埠繫結成功,客戶端已經進入正常監聽狀態,可以繼續設定系統代理或瀏覽器擴充功能。
如果改完埠問題依舊存在
極少數情況下,即便換了一個「看起來空閒」的埠依然報同樣的繫結錯誤,可以按下面幾點繼續排查:
-
確認改動的是正在載入的那份設定
部分客戶端有多套設定檔(profile),修改了 A 份但客戶端實際載入的是 B 份,改動自然不會生效。
-
檢查是否有安全軟體攔截了埠監聽
部分安全防護軟體會攔截未知程式對本機埠的繫結行為,把 Clash 客戶端加入信任清單或暫時關閉相關攔截項後再測試。
-
換一個完全不常見的埠號重新測試
有些號段被系統或其他背景服務保留,換成五位數、非整千的埠號(如 27891)再試一次,排除號段本身的問題。
把這些環節逐一確認一遍,基本能覆蓋埠占用類問題的絕大多數場景。這類故障的核心始終是同一句話:先用系統指令確認埠到底被誰占了,再決定關閉對方還是給 Clash 換一個埠,不需要重裝客戶端或重新下載訂閱。