故障排查 预计阅读 12 分钟

Clash 7890 端口被占用怎么办:定位占用进程与修改混合端口

启动报 address already in use 时,如何在 Windows、macOS、Linux 上查出占用进程,并安全改掉 mixed-port 与外部控制端口。

先读报错:确认冲突的是代理端口还是控制端口

Clash 或 mihomo 启动时出现 bind: address already in use,表示内核尝试监听的本地地址与端口无法按当前方式绑定,常见原因是已有进程占用了同一监听地址。此时先排查本机监听,不必重新购买订阅,也不必先换代理节点。订阅里的远程服务器端口与电脑上的 7890 是两个不同位置。

打开客户端日志,复制包含 listen、bind 和端口号的完整一行。下面是用于辨认字段的示例,并非所有客户端都会输出相同前缀:

listen tcp 127.0.0.1:7890: bind: address already in use
listen tcp 127.0.0.1:9090: bind: address already in use
配置字段用途排查重点
mixed-port: 7890同一入口接收 HTTP 与 SOCKS 代理连接浏览器、系统代理和命令行应连接此入口
port: 7891单独的 HTTP 代理入口检查是否与混合入口重复
socks-port: 7892单独的 SOCKS 代理入口检查独立 SOCKS 监听及相关应用设置
external-controller: 127.0.0.1:9090提供管理 API,供客户端或面板控制内核不能当成浏览器代理端口使用

表中端口是说明用的配置值,不是所有客户端的默认值。以日志和最终生效配置为准。日志写的是 9090,就先检查控制接口;只把 mixed-port 从 7890 改成其他值,无法解除控制接口的冲突。

Windows:用 netstat 和 PowerShell 定位占用进程

1. 查 7890 的监听 PID

打开「开始」→ 搜索「终端」或「PowerShell」。先执行查询;若读取其他用户进程或停止服务时提示权限不足,再以管理员身份打开。以下命令只读取状态,不会结束进程:

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

重点看本地地址为 127.0.0.1:7890、0.0.0.0:7890 或 [::]:7890 且状态为 LISTENING 的行。最后一列是 PID。包含 :7890 的结果也可能只是远程连接,不能把每一行都认定为监听占用。需要精确过滤本地监听时,使用:

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

2. 查进程路径,区分托盘程序和后台服务

假设查询返回 PID 1234,下面的数字应替换为实际 PID。先查看名称,再查看可执行文件路径与启动参数:

tasklist /FI "PID eq 1234"

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

常见情况是旧客户端仍在托盘运行、新客户端又启动了一份内核;也可能是服务模式中的 mihomo 已经监听,而图形界面另外启动了第二份。优先从对应客户端菜单选择「退出」,或在「任务管理器」→「详细信息」核对 PID。对于已确认的后台服务,进入「服务」管理器检查其名称与可执行路径,再决定停止哪个服务。

若正常退出后进程仍未结束,可以对已确认的 PID 执行 Stop-Process -Id 1234。结束前先保存配置,并确认它不是其他用户正在使用的服务。不要使用按名称批量终止所有代理进程的命令。

3. 没有监听结果,但仍无法绑定

先重新读取最新日志,区分 address already in use 与 access permissions。后者可能涉及系统保留端口或安全策略,不能直接当成普通占用处理。Windows 可继续查询 TCP 排除范围:

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

如果目标端口位于列出的范围内,优先选择范围外的空闲端口。不要为了固定使用 7890 而随意删除系统排除范围;虚拟化、容器和网络共享功能可能依赖这些设置。

macOS 与 Linux:查监听地址,再确认启动来源

macOS:使用 lsof

打开「应用程序」→「实用工具」→「终端」,执行以下命令。-nP 保留数字地址和端口,避免名称解析影响阅读;-sTCP:LISTEN 只看 TCP 监听。

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

读取输出中的 COMMAND、PID 和 NAME。假设 PID 为 1234,继续确认启动命令:

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

先通过菜单栏退出对应客户端。若是手动启动的内核,回到原终端按 Control-C。确认属于可停止的残留进程后,才使用 kill -TERM 1234。如果 PID 很快更换并重新监听,检查「系统设置」→「通用」→「登录项与扩展」及自己配置的 launchd 服务,处理自动拉起的来源。

Linux:使用 ss,检查 systemd 服务

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

ss 的 -l 表示监听,-t 表示 TCP,-n 使用数字,-p 显示进程。若输出指向 systemd 管理的内核,先确认实际单元名。只有安装时确实使用了 mihomo.service,才执行下面这组命令:

systemctl status mihomo.service
sudo systemctl stop mihomo.service

用户级服务则使用 systemctl --user 查询和管理。若配置是 Docker 部署,还应检查 docker ps 中的宿主机端口映射;占用宿主机 7890 的可能是容器发布端口,而不是当前桌面客户端。

修改 mixed-port:先选择空闲端口,再改生效配置

如果原有程序确实需要继续使用 7890,可以给当前 Clash 客户端换一个入口,例如 17890。这个数字仅是示例,不保证本机空闲;先把前面的查询命令中的 7890 换为 17890 检查。

最小本地监听配置

mixed-port: 17890
allow-lan: false
bind-address: 127.0.0.1

external-controller: 127.0.0.1:19090
secret: "local-api-19090-change-before-use"

这只是用于说明监听字段的 YAML 片段,不包含节点、策略组或规则,不能直接替代完整订阅。示例同时演示把控制端口设为 19090;若原控制端口没有冲突,可以保留原值。secret 的示例内容需要改为自行生成的随机字符串,并同步给管理面板。

  • 保持顶层字段唯一:修改已有的 mixed-port,不要在文末再追加第二个同名键。YAML 缩进使用空格,不使用 Tab。
  • 检查独立端口:若同时启用了 port 或 socks-port,不要让这些独立监听与混合端口使用相同地址和端口。只需混合入口时,可按客户端支持方式停用多余入口。
  • 确认监听范围:本机使用保持 allow-lan: false。不要为解决冲突而改成监听所有网卡,这可能扩大代理入口的可访问范围。
  • 控制接口只留本地:external-controller 用于管理 API。绑定 127.0.0.1 并设置密钥,不要直接暴露到公网。

订阅文件、覆写与运行配置的区别

带图形界面的客户端通常会合并订阅与本地设置,生成实际交给 mihomo 的配置。直接编辑下载缓存里的 YAML,可能在下一次订阅更新后被覆盖;编辑临时运行文件,也可能在重启时丢失。优先查找客户端提供的「混合端口」「端口设置」或「覆写」入口,具体名称以当前客户端界面为准。

修改后保存并重启内核,而不是只关闭设置窗口。随后查看启动日志中的监听端口,或重新运行监听查询。使用独立 mihomo 二进制时,可以先在配置文件所在目录执行 mihomo -t -f config.yaml 检查配置;语法检查通过并不等于端口一定可绑定,还要看真正启动后的结果。

端口改好后,同步系统代理与命令行环境

内核监听 17890 后,仍把流量发往 7890 的应用会连接失败,或误连到原来的另一份代理。可以先关闭客户端的「系统代理」,再重新开启,并检查操作系统最终保存的地址。

  • Windows 11:「设置」→「网络和 Internet」→「代理」→「手动设置代理」。若使用手动代理,服务器填 127.0.0.1,端口填 17890。使用 PAC 时应检查 PAC 规则提供的目标,而不是只修改手动代理。
  • macOS:「系统设置」→「网络」→ 当前网络连接 →「详细信息」→「代理」。核对已启用的网页代理、安全网页代理或 SOCKS 代理端口。
  • 独立应用:浏览器代理扩展、下载工具、编辑器和 Git 的自定义代理不会必然随系统设置更新,需要分别检查。

命令行还可能读取环境变量。下面分别查看 Windows PowerShell 与 macOS、Linux 当前终端中的代理变量:

# Windows PowerShell
Get-ChildItem Env: | Where-Object Name -Match 'proxy'

# macOS / Linux
env | grep -i proxy

例如原来设置了 HTTPS_PROXY=http://127.0.0.1:7890,就需要同步改到新端口。此处 http:// 表示与本地 HTTP 代理入口的通信方式,不是要求目标网站只能使用 HTTP。永久环境变量修改后,通常需要重新打开终端,旧进程不会自动获得新值。

TUN 模式接管进入虚拟网卡的流量,与混合端口监听属于不同环节。开启 TUN 不会自动释放被其他进程占用的 7890;显式使用 HTTP 或 SOCKS 代理的应用仍需检查自己的端口。规则模式、全局模式的切换也不能解除本地监听冲突。

验证修复:监听、代理请求、重启后配置各查一次

  1. 检查监听进程:重新查询 17890,确认 PID 对应预期的 Clash 或 mihomo 实例。再检查原报错端口,判断是否仍由另一项服务使用。
  2. 检查启动日志:确认没有新的绑定失败。若还有 9090、7891 等报错,应分别处理,不能只凭一个入口启动成功就结束排查。
  3. 显式发送代理请求:使用下面的 curl 命令,避免单凭浏览器页面缓存判断代理是否可用。
  4. 验证持久设置:重启客户端后再次检查。下一次订阅更新后也要核对端口,确认本地覆写仍然生效。
# Windows PowerShell
curl.exe --noproxy "" -I --connect-timeout 5 --max-time 15 --proxy http://127.0.0.1:17890 https://example.com/

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

这里的 --noproxy "" 用来清空本次请求的代理绕过列表,--connect-timeout 5 和 --max-time 15 分别限制连接阶段与整次请求的等待时间。这些是测试参数,不是速度测量结果。

如果立即显示无法连接 127.0.0.1:17890,回到监听与地址检查;如果已连接本地代理,但后续出现 TLS、DNS 或远程超时,排查重点才转向节点、DNS 与规则。HTTPS 测试中仅看到 200 Connection established,只说明代理接受了 CONNECT 隧道请求,还应继续看目标站响应及客户端日志。

常见追问:重装、防火墙与两份客户端并行运行

重装 Clash 能直接解决 7890 占用吗?

如果占用来自另一份仍在运行的内核,重装当前客户端通常不会停止那个进程。先用 PID 找到来源,比反复卸载更直接。删除配置还可能丢失订阅和覆写,排查前应保留需要的本地设置。

关闭防火墙能解决 address already in use 吗?

防火墙主要影响连接能否通过,不会替应用释放已经被占用的监听端口。绑定失败与局域网设备访问失败是不同问题。不要把关闭防火墙作为本地端口冲突的第一步。

两份 Clash 客户端能同时运行吗?

可以分别配置不冲突的监听端口和控制端口,但还需协调系统代理、TUN 路由以及 DNS 接管。对一般桌面使用,保留一份负责系统网络的内核更容易维护。确实需要并行测试时,可让第二份只提供独立的本地代理入口,不同时抢占系统代理与 TUN。

日志写 UDP 端口占用,也用同一组命令吗?

前文主要查询 TCP 监听。若日志明确写的是 UDP,应按传输协议另外检查:Windows 用 Get-NetUDPEndpoint -LocalPort 7890,macOS 用 sudo lsof -nP -iUDP:7890,Linux 用 sudo ss -lunp 'sport = :7890'。TCP 与 UDP 是不同的端口空间,TCP 查询没有结果不能证明 UDP 端口空闲。

修复完成的判断标准是:预期内核成功监听、使用新端口的请求能完成、重启与订阅更新后设置保持一致。后续如仍有连接问题,可到帮助中心区分 DNS、订阅和规则故障,或在进阶配置中继续核对 mihomo 的配置职责。

下载Clash