先确认报错来自哪个监听端口
Clash 启动时提示端口被占用,通常发生在内核创建本地监听器的阶段。日志中的 bind: address already in use 表示目标地址与端口无法按当前方式绑定;Windows 上也可能出现 Only one usage of each socket address。这类错误与订阅是否过期、节点能否连通不是同一层问题,先更换节点往往没有作用。
mixed-port 在同一个端口接受 HTTP 与 SOCKS 代理连接。本文用 7890 作为旧端口、17890 作为新端口演示,二者都只是示例值,不能据此认为本机一定使用 7890,或者 17890 一定空闲。先打开客户端日志,记录报错行中的地址、端口和协议。
| 字段 | 用途 | 处理方向 |
|---|---|---|
mixed-port | HTTP 与 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 的代理入口通常比中断该服务更合适。
- 记录当前端口、系统代理地址和应用单独配置的代理地址。
- 查询候选端口
17890,方法与查询 7890 相同。 - 确认准备保留的客户端和内核实例,避免同时修改两套配置。
- 修改实际生效的配置来源,重新加载或重启内核。
- 核对新监听,再更新系统和应用使用的端口。
在 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 | 「设置」→「网络和 Internet」→「代理」→「手动设置代理」→「编辑」 | 地址 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 代理环境变量,不会修改所有应用的设置。HTTPS 目标通过本地 HTTP 代理建立隧道时,代理地址仍可使用 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 后网页能打开,不能证明旧系统代理端口已修正;某些客户端还可能因为混合入口冲突而出现部分功能启动失败。验收时仍应分别确认日志、本地监听与请求走向。