先读日志:7890 是代理入口,9090 是控制接口

Clash 或使用 mihomo 内核的客户端启动失败,先展开内核日志,找到包含 listen、bind 和具体地址的错误行。看到 address already in use,通常表示该地址与端口已有监听者。Windows 上也可能出现“通常每个套接字地址只允许使用一次”的提示。先记录端口、绑定地址与协议,再决定停止进程还是修改配置。

7890 与 9090 是常见配置值,并非所有客户端都固定使用它们。实际入口以当前生效配置和启动日志为准。两类端口用途不同,不能看到一个报错就把所有端口一起改掉。

配置项示例值用途与影响
mixed-port7890在同一入口接受 HTTP 代理与 SOCKS5 连接,浏览器、终端或系统代理可能使用它。
external-controller127.0.0.1:9090提供控制 API,供客户端或 Web 面板读取状态、切换策略,不是网页代理入口。
port7892独立 HTTP 代理入口;只有启用该项时才需要检查。
socks-port7893独立 SOCKS 入口,不能只改 mixed-port 就假定它也已改变。

Windows:用 netstat 与 PowerShell 找到占用进程

第一步:查看监听状态,不只搜索数字

打开 PowerShell,执行下面两条命令。输出中的“本地地址”应以目标端口结尾,状态应为 LISTENING;最后一列是进程 ID,即 PID。单纯搜索 7890 也可能命中远程地址或其他端口数字,因此必须看完整列。

netstat -ano -p tcp | findstr ":7890"
netstat -ano -p tcp | findstr ":9090"

也可以直接用 PowerShell 按本地端口筛选监听者,避免将已建立的连接误认为端口占用:

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

127.0.0.1:7890 表示 IPv4 回环监听;0.0.0.0:7890 表示所有 IPv4 接口。后者通常也会阻止另一个程序再绑定本机的同端口。IPv6 的 [::]:7890 是否同时影响 IPv4,还与套接字设置有关,排查时不要忽略 IPv6 输出。

第二步:确认程序路径,再退出重复实例

下面用 PID 1234 演示查询命令;执行时应改成上一条输出中的真实 PID。PID 会随进程重启变化,不能照抄示例后直接结束进程。

tasklist /FI "PID eq 1234"
Get-Process -Id 1234 | Select-Object Id,ProcessName,Path
  • 另一款代理客户端:先从系统托盘退出另一款客户端,同时关闭其开机启动或自动启动内核功能,再启动需要保留的客户端。
  • 同一客户端的后台内核:关闭窗口可能只是最小化到托盘。使用托盘中的退出操作,再检查监听是否消失。
  • 由服务管理的进程:先确认服务归属,通过所属客户端或“服务”管理器停止。只结束子进程,守护程序可能立即重新拉起它。
  • 其他开发工具:若端口属于正在使用的服务,保留该服务,改 Clash 端口通常更合适。

查询路径时遇到权限不足,可以用管理员身份重新打开终端。不要根据进程名相似就结束系统服务,也不要把“以管理员身份运行”当成解决所有绑定冲突的方法:管理员权限不会自动释放已经被另一个进程占用的端口。

macOS 与 Linux:用 lsof 或 ss 确认监听者

macOS 可在“终端”中使用 lsof。Linux 安装了该工具时也可以使用同样的命令。-nP 保持数字地址和端口,-sTCP:LISTEN 只列 TCP 监听,便于直接核对 PID 与进程名。

sudo lsof -nP -iTCP:7890 -sTCP:LISTEN
sudo lsof -nP -iTCP:9090 -sTCP:LISTEN

Linux 也可用 ss 一次查询两个端口。若普通用户看不到进程信息,再提升权限,而不是先反复重启内核。

sudo ss -ltnp '( sport = :7890 or sport = :9090 )'

桌面客户端与 systemd 服务不要重复启动同一个入口

Linux 上常见的冲突是:之前已将 mihomo 配成后台服务,后来又打开带内核的桌面客户端。两者读取不同配置,却都尝试监听 7890。如果部署时使用的服务名确实是 mihomo.service,可先检查状态与日志:

systemctl status mihomo --no-pager
journalctl -u mihomo -n 50 --no-pager

确认要改用桌面客户端后,可执行 sudo systemctl stop mihomo 停止该服务;是否关闭其开机启动应根据实际部署决定。若服务名不同,应使用真实名称。macOS 则优先从菜单栏退出旧客户端;如果内核来自后台启动任务,需要通过原来的管理方式停止,否则结束一次进程后仍可能再次出现。

修改 mixed-port:配置入口与应用代理一起更新

先备份,再确定谁生成最终配置

图形客户端可能通过设置页、覆写配置或配置合并机制生成内核运行文件。直接修改缓存中的订阅 YAML,可能在更新订阅或重启客户端后被覆盖。因此先备份配置,再在当前客户端提供的持久化设置入口修改端口;具体菜单名随客户端而异,不要把某个客户端的菜单路径套用到所有软件。

  1. 查询准备使用的新端口,例如 7891 与 9091,确认没有已有监听。
  2. 如果界面提供“混合端口”字段,将其改为 7891 并保存;手动部署则修改实际加载的配置文件。
  3. 按客户端要求重载配置或重启内核,再查看日志中的实际监听地址。
  4. 更新系统代理、浏览器代理扩展、命令行环境变量和其他手工配置的代理地址。

以下是需要合并到现有配置顶层的片段,不是可以单独导入使用的完整订阅。现有节点、策略组和规则应保留;已有同名键要修改原值,不要重复追加。两个新端口只是示例,使用前仍需确认空闲。

config.yaml · 端口配置片段
mixed-port: 7891
allow-lan: false
external-controller: 127.0.0.1:9091

同时检查是否还启用了独立的 port、socks-port、redir-port 或 tproxy-port。报错指向哪个入口,就处理哪个入口。不要把多个需要独立监听的入口都改成相同的地址与端口。

系统代理与终端变量分别检查

Windows 11 可在「设置」→「网络和 Internet」→「代理」→「手动设置代理」中核对地址与端口;macOS 可在「系统设置」→「网络」→当前网络服务→「详细信息」→「代理」中核对。若客户端负责自动设置系统代理,通常应由客户端重新应用设置,避免手动值随后又被它覆盖。

终端环境变量不会因为系统代理变化而自动更新。下面只修改当前终端会话,适合验证新端口;如果启动脚本或开发工具配置里仍写着 7890,也要另行修改。

PowerShell · 当前会话
$env:HTTP_PROXY = "http://127.0.0.1:7891"
$env:HTTPS_PROXY = "http://127.0.0.1:7891"
macOS / Linux · 当前 shell
export http_proxy=http://127.0.0.1:7891
export https_proxy=http://127.0.0.1:7891

HTTPS_PROXY 的变量名表示用于 HTTPS 目标的代理设置,不代表本地代理地址必须写成 https://。这里连接的是本地 HTTP 代理入口,因此仍使用 http://127.0.0.1:7891。如果还设置了 ALL_PROXY 或应用专用代理,需一并检查;不同工具对大小写变量及优先级的处理不同。

修改 9090:同步控制面板地址与认证设置

若冲突的是 external-controller,将它改为 127.0.0.1:9091 后,Web 面板中的后端地址也应改成 http://127.0.0.1:9091。现有 secret 应保留,并在面板中填写匹配的认证信息。部分桌面客户端会自行管理控制接口与认证值,应优先通过其设置修改,避免前端和内核配置不一致。

  • 代理可用,面板断开:先查面板是否还连接旧的 9090,再查认证信息和客户端日志。
  • 接口返回 401:通常说明 HTTP 服务已响应,但请求缺少有效认证,不等于端口仍被占用。
  • 连接被拒绝:通常表示该地址当时没有可接受连接的监听者,继续检查内核是否启动、绑定地址是否正确。

改完如何验证:监听、代理、控制接口分开测

一、确认新端口由预期进程监听

重新运行前面的查询命令,把端口替换成 7891 和 9091。结果不仅要有监听,还要确认 PID 属于当前需要的内核。如果旧进程没有退出,浏览器仍指向旧端口时,可能造成“已经修好”的错觉。

二、显式指定代理,排除系统代理残留

Windows PowerShell 使用 curl.exe,避免某些环境将 curl 解析为其他命令。macOS 与 Linux 使用 curl 即可。下面的命令明确连接新入口,--noproxy "" 用于清空本次请求的绕过列表;示例目标仅用于连通性检查,不是测速基准。

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

收到目标站点响应,说明本地代理入口至少已能处理这次请求。但请求最终可能按规则走 DIRECT,不能仅凭命令成功断言某个远端节点可用。应结合客户端连接记录,查看该域名命中的规则、策略组和实际出口。

三、单独检查控制 API

curl.exe --connect-timeout 5 --max-time 10 -i http://127.0.0.1:9091/version

macOS 与 Linux 将命令中的 curl.exe 改为 curl。未启用认证时,正常接口可返回版本信息;启用认证时,未附带凭据可能返回 401。不要为方便测试删除已有密钥,也不要把包含真实密钥的完整命令或日志截图公开。

没有监听者仍无法绑定:检查保留端口与错误类型

如果日志是 permission denied、access permissions 或 cannot assign requested address,不应继续按照普通占用处理。Windows 的端口排除范围、绑定了不存在的本机地址,以及安全软件限制,都可能产生不同类型的绑定失败。

Windows 可用以下命令检查 TCP 排除范围。若目标端口落在范围内,优先选择范围外的空闲端口,并检查虚拟化或网络组件的相关配置;不要直接删除系统管理的排除项。

netsh interface ipv4 show excludedportrange protocol=tcp
netsh interface ipv6 show excludedportrange protocol=tcp

如果错误指向 UDP 监听,前文只查 TCP 的命令不会给出完整结论。Windows 可执行 Get-NetUDPEndpoint -LocalPort 7890,Linux 可执行 sudo ss -lunp,macOS 可执行 sudo lsof -nP -iUDP:7890。TCP 与 UDP 是不同的端口空间,应按日志中失败的协议分别排查。

最后检查是否改到了错误的配置文件。使用服务启动的 mihomo 可能通过启动参数指定另一个配置目录;桌面客户端也可能在运行时生成配置。若重启后仍监听旧端口,应先确认配置来源与覆写顺序,而不是不断更换数字。

端口冲突排查清单

  1. 读日志:记录失败的地址、端口、TCP 或 UDP,以及完整错误类型。
  2. 查归属:用 netstat、lsof 或 ss 找到监听 PID,核对程序路径和启动方式。
  3. 做选择:停止不再需要的重复实例,或为需要并存的服务设置不同端口。
  4. 改持久配置:修改真正生效的 mixed-port 或 external-controller,避免订阅更新后恢复旧值。
  5. 同步使用方:代理端口对应系统代理和应用设置;控制端口对应面板后端地址与认证信息。
  6. 分层验证:先看监听,再测显式代理,最后测控制 API 和规则命中结果。

TUN 模式通过虚拟网卡接管流量,与本地代理监听不是同一个层面。打开 TUN 不会自动释放被占用的 7890 或 9090。先处理日志里明确报错的监听入口,再排查 TUN 权限、路由或 DNS,能减少多个问题互相干扰。