先确认冲突的是哪个监听端口

Clash、Clash Meta(mihomo)或图形客户端启动失败时,日志里常见的关键信息是 bind: address already in uselisten tcp 127.0.0.1:7890Only one usage of each socket address is normally permitted。这些信息都指向同一类问题:内核准备监听本机端口,但该地址与端口组合已经被另一个进程占用。

不要看到 7890 就直接修改配置。先读完整日志,确认失败的是 HTTP、SOCKS、混合代理、控制器还是 DNS 监听。不同端口承担的职责不同,修改后需要同步调整的客户端设置也不同。

配置项 常见端口 用途 冲突后的直接影响
port 7890 HTTP 代理监听 浏览器或系统 HTTP 代理无法连接
socks-port 7891 SOCKS5 代理监听 使用 SOCKS5 的应用连接失败
mixed-port 7890 同一端口接受 HTTP 与 SOCKS5 两类代理入口同时不可用
external-controller 9090 控制面板与客户端调用内核 API 界面可能显示内核断开或无法读取策略组
dns.listen 1053 本地 DNS 服务 域名解析模块启动失败
redir-port 7892 Linux 透明代理重定向入口 基于防火墙重定向的流量无法进入内核
tproxy-port 7893 Linux TProxy 透明代理入口 透明代理规则命中后连接失败

日志中的地址也要一起看

  • 127.0.0.1:7890:只监听 IPv4 本机回环地址,局域网设备不能直接访问。
  • 0.0.0.0:7890:监听全部 IPv4 网络接口,通常与客户端中的「允许局域网」相关。
  • [::]:7890:监听 IPv6 全部接口。在部分系统上,它也可能影响同端口的 IPv4 监听。
  • 127.0.0.1:9090:一般是外部控制器,不是浏览器应填写的代理端口。

端口号相同但监听地址不同,不一定发生冲突;是否允许并存取决于操作系统、IPv6 双栈行为和程序设置。排查时应同时记录协议、监听地址、端口与进程 ID,而不是只记一个数字。

Windows 用 netstat 定位端口占用进程

Windows 10 与 Windows 11 都可以直接使用系统自带的 netstat。先完全关闭 Clash 客户端,然后以普通权限打开 PowerShell 或命令提示符,检查 7890 是否仍有监听者。

步骤一:查找 7890 的监听记录

netstat -ano | findstr :7890

输出可能包含多行。重点找状态为 LISTENING 的 TCP 记录,最后一列是 PID。例如下面的 PID 为 14672:

TCP    127.0.0.1:7890    0.0.0.0:0    LISTENING    14672

findstr :7890 也会匹配正在连接远端 7890 端口的记录,因此不能只看端口数字。必须确认 7890 位于“本地地址”一列,并且状态是 LISTENING

步骤二:把 PID 对应到程序

tasklist /FI "PID eq 14672"

如果返回 mihomo.execlash.exe 或另一个代理客户端的内核文件,通常表示旧实例没有退出。若返回开发服务器、容器端口转发工具或其他本地网络程序,则需要判断哪个程序更适合改端口。

也可以打开「任务管理器」→「详细信息」,点击 PID 列排序后查找 14672。任务管理器默认没有显示 PID 时,在表头右键选择「选择列」→「PID(进程标识符)」。

步骤三:用 PowerShell 分别检查 TCP 与 UDP

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

Get-Process -Id 14672

DNS、TProxy 或部分转发入口还可能使用 UDP。检查 UDP 端点时执行:

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

UDP 没有 LISTENING 状态,所以不能照搬 TCP 的过滤条件。如果 Clash 日志明确写着 listen udp,应使用 Get-NetUDPEndpointnetstat -ano -p udp

步骤四:优先正常退出,不要直接强制结束

  1. 如果占用者是另一个代理客户端,从其托盘菜单选择退出。
  2. 如果占用者作为 Windows 服务运行,打开 services.msc,找到对应服务后停止。
  3. 确认进程不再承担下载、容器转发或开发任务后,再考虑结束进程。
  4. 重新执行 netstat -ano | findstr :7890,确认监听记录已经消失。

强制结束进程只能解除当前占用。如果该程序设置了开机启动、服务自动恢复或崩溃后重启,端口会在数秒后再次出现。此时应修改启动项或为其中一个程序分配固定的新端口。

macOS 与 Linux 用 lsof、ss 查找冲突

macOS 可以用系统自带的 lsof 检查监听者。关闭 Clash 图形客户端后打开「终端」,执行下面的命令:

lsof -nP -iTCP:7890 -sTCP:LISTEN

-nP 会保留数字形式的地址与端口,避免主机名解析影响速度。输出中的 COMMAND 是程序名,PID 是进程 ID。需要查看完整启动参数时,可以继续执行:

ps -p 14672 -o pid,ppid,user,command

检查 UDP 监听可使用:

lsof -nP -iUDP:1053

如果旧内核由客户端拉起,先从 macOS 菜单栏退出客户端。直接执行 kill 14672 后,客户端的守护逻辑可能马上重新启动内核,结果会表现为 PID 变化但 7890 始终被占。

Linux 优先使用 ss

现代 Linux 发行版通常预装 ss。以下命令会显示监听 7890 的 TCP 进程:

sudo ss -ltnp 'sport = :7890'

检查 DNS 监听或其他 UDP 端口:

sudo ss -lunp 'sport = :1053'

如果 mihomo 由 systemd 管理,还要检查服务状态。服务名由安装方式决定,常见命令如下:

systemctl --type=service | grep -Ei 'clash|mihomo'
sudo systemctl status mihomo

确认是重复服务后,使用对应服务名停止旧实例,再决定是否禁用其自动启动。不要在不清楚用途时直接删除服务文件,因为服务配置里可能还包含 TUN 权限、路由初始化和防火墙清理步骤。

修改 mixed-port、port 与控制器端口

如果冲突程序必须继续使用原端口,就给 Clash 分配一个未占用端口。建议选择 1024 以上、当前没有监听记录的端口,例如把 7890 改为 17890。端口范围是 1 至 65535,但低于 1024 的端口在 macOS 与 Linux 上通常需要额外权限,不适合作为普通桌面客户端的代理入口。

只使用 mixed-port 的配置

mixed-port 可以在同一端口接收 HTTP 代理和 SOCKS5 代理。对于只需要一个本地入口的桌面环境,配置较直接:

mixed-port: 17890
allow-lan: false
bind-address: 127.0.0.1
external-controller: 127.0.0.1:19090

修改后,系统代理的 HTTP 与 HTTPS 地址都应指向 127.0.0.1:17890。使用 SOCKS5 的应用同样填写 127.0.0.1:17890,但协议类型要选择 SOCKS5。

HTTP 与 SOCKS5 分开监听

port: 17890
socks-port: 17891
allow-lan: false
external-controller: 127.0.0.1:19090

这种写法适合需要明确区分协议的环境。浏览器手动代理或系统 HTTP 代理使用 17890,支持 SOCKS5 的终端工具使用 17891。不要同时把 mixed-portport 配成相同端口,否则内核仍然会因为重复绑定而启动失败。

DNS 监听端口的修改方式

dns:
  enable: true
  listen: 127.0.0.1:11053
  enhanced-mode: fake-ip

把 DNS 从 1053 改到 11053 后,依赖该监听地址的转发器也要同步修改。例如本机 dnsmasq、路由规则或客户端的 DNS 劫持配置如果仍指向 1053,域名请求不会自动转到新端口。

图形客户端中修改时注意配置来源

不同客户端的菜单名称会有差异。常见入口是「设置」→「参数设置」→「端口设置」,或「设置」→「Clash 设置」→「混合端口」。保存后应执行一次「重启内核」,而不只是关闭设置窗口。

如果端口来自订阅配置,直接编辑当前 YAML 可能在更新订阅后被覆盖。更稳定的做法是使用客户端提供的覆写功能,例如「配置」→「覆写」→「端口」,把本地端口值作为持久设置。若客户端没有覆写功能,应记录修改项,并在订阅更新后检查端口是否恢复。

修改后验证端口、系统代理与实际连接

配置保存成功不等于故障已经结束。完整验证应包含四步:确认旧端口释放、确认新端口开始监听、确认系统代理同步更新、最后发起一次真实的代理请求。

1. 确认新端口处于监听状态

Windows 执行:

netstat -ano | findstr :17890
Test-NetConnection 127.0.0.1 -Port 17890

Test-NetConnection 的结果中,TcpTestSucceeded 应为 True。macOS 或 Linux 可执行:

lsof -nP -iTCP:17890 -sTCP:LISTEN

同时再次检查 7890。如果旧端口仍被另一个程序监听并不一定影响 Clash,但这能证明最初的冲突来源确实还在,新旧程序现在通过不同端口并存。

2. 检查系统代理是否仍指向旧端口

  • Windows 11:进入「设置」→「网络和 Internet」→「代理」,检查手动代理服务器的端口。
  • macOS:进入「系统设置」→「网络」→当前网络→「详细信息」→「代理」,检查网页代理与安全网页代理。
  • 浏览器扩展:检查代理情景模式中的 HTTP、HTTPS 或 SOCKS5 端口。
  • 终端环境变量:检查 HTTP_PROXYHTTPS_PROXYALL_PROXY 是否仍包含 7890。

多数 Clash 图形客户端在启用「系统代理」后会自动写入新端口,但手动配置的浏览器、开发工具和命令行环境不会自动更新。端口修改后出现“客户端显示运行,浏览器却无法访问”的情况,通常就是调用方仍连接旧端口。

3. 用 curl 发起明确的代理请求

curl -I -x http://127.0.0.1:17890 https://example.com

如果使用独立 SOCKS5 端口 17891,可以执行:

curl -I --socks5-hostname 127.0.0.1:17891 https://example.com

命令能够返回 HTTP 响应头,说明本地端口接受连接、代理协议匹配,并且请求已经完成。若出现 Connection refused,新端口没有监听;若长时间超时,应继续检查节点、策略组、DNS 与网络连通性;若返回协议错误,则可能把 HTTP 客户端连到了只接受 SOCKS5 的端口。

4. 观察内核日志与连接列表

打开客户端的「日志」页面,把级别设为 info。发起测试请求时,应看到目标域名、匹配规则和最终策略,例如域名命中 DOMAIN-SUFFIX 后转到某个代理组。再打开「连接」页面,确认来源地址是 127.0.0.1,并检查上传、下载字节数是否变化。

反复出现端口冲突时的排查顺序

端口修改后过一段时间再次冲突,通常意味着系统中存在自动启动或配置覆盖。按下面顺序检查,比反复更换端口更容易找到根因。

  1. 检查两个 Clash 客户端是否同时自启动。例如旧客户端保留在登录项,新客户端也设置了开机启动,两者都会尝试监听 7890。
  2. 检查 GUI 与独立内核服务是否重复。图形客户端已经管理 mihomo 时,不应再让 systemd、launchd 或 Windows 服务启动另一份相同配置。
  3. 检查订阅更新后的覆写结果。更新前是 17890,更新后重新变成 7890,说明本地修改没有进入持久覆写。
  4. 检查 external-controller。代理端口正常但界面一直提示连接失败时,冲突点可能是 9090,而不是 7890。
  5. 检查 DNS 的 TCP 与 UDP。某些 DNS 服务会同时监听两种协议,只检查 TCP 可能遗漏 UDP 1053 的占用。
  6. 检查允许局域网带来的监听范围变化。127.0.0.1 切换到 0.0.0.0 后,新监听会覆盖更多接口,可能与原有服务发生冲突。

一组可长期使用的端口规划

服务 示例端口 调用方
混合代理 17890 系统代理、浏览器、命令行工具
外部控制器 19090 Clash 图形界面或 Web 控制面板
本地 DNS 11053 TUN DNS 劫持、本地转发器
独立 SOCKS5 17891 需要单独 SOCKS5 入口的应用

端口数字本身不影响规则匹配、节点延迟或代理速度。关键是确保每个监听地址只由预期进程占用,并让系统代理、浏览器、DNS 转发器和控制面板使用相同的新配置。完成修改后保留一份端口记录,之后升级客户端、切换内核或更新订阅时即可快速核对。