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 代理的应用仍需检查自己的端口。规则模式、全局模式的切换也不能解除本地监听冲突。
验证修复:监听、代理请求、重启后配置各查一次
- 检查监听进程:重新查询
17890,确认 PID 对应预期的 Clash 或 mihomo 实例。再检查原报错端口,判断是否仍由另一项服务使用。 - 检查启动日志:确认没有新的绑定失败。若还有
9090、7891等报错,应分别处理,不能只凭一个入口启动成功就结束排查。 - 显式发送代理请求:使用下面的 curl 命令,避免单凭浏览器页面缓存判断代理是否可用。
- 验证持久设置:重启客户端后再次检查。下一次订阅更新后也要核对端口,确认本地覆写仍然生效。
# 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 的配置职责。