故障排查 预计阅读 11 分钟

Clash 端口 7890 被占用:查找占用进程与修改混合端口

客户端启动失败提示端口已被占用时,用 netstat、lsof 等命令找到占用进程,再修改 mixed-port 与外部控制端口并同步系统代理设置。

先确认日志里的监听地址与端口

Clash 提示端口占用,通常表示内核无法在指定地址上建立监听。常见触发场景是同时启动两款代理客户端、旧内核退出不完整,或后台服务已占用同一端口。此时更新订阅、切换节点和改分流规则都不能解除本机的监听冲突。

先打开客户端的「日志」页面,找到含有 bind、listen 或 address already in use 的完整记录。Windows 也可能显示 Only one usage of each socket address。下面是用于识别错误类型的示例,不是本机实测输出:

listen tcp 127.0.0.1:7890: bind: address already in use
listen tcp 127.0.0.1:9090: bind: address already in use

第一行涉及本地代理入口,第二行涉及控制接口。必须按实际报错端口排查,不要看到 Clash 启动异常就只检查 7890。若日志写的是 permission denied 或禁止访问套接字,则还要考虑权限、系统端口保留范围或安全策略,不应直接认定有其他进程占用。

配置项用途与示例修改后的影响
mixed-portHTTP 与 SOCKS 共用入口,例如 7890系统代理及手动指定代理的应用需要同步
port / socks-port分别提供 HTTP、SOCKS 入口,取值以配置为准对应协议的应用需要同步
external-controller控制接口,例如 127.0.0.1:9090面板或客户端连接内核的设置可能需要同步

Windows:用 netstat 查 PID,再核对程序路径

在 PowerShell 中定位监听进程

右键点击「开始」→「终端」,在 PowerShell 标签页执行以下命令。查询一般不需要管理员权限;遇到进程信息不可见时,再以管理员身份打开终端。

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

重点看本地地址列是否以 :7890 结尾,以及状态是否为 LISTENING。远端地址恰好含有 7890,或者连接状态为 TIME_WAIT,都不能单独证明某个程序正在监听本地 7890。每行最右侧的数字是 PID。

若希望只列出目标监听端口,可直接使用 PowerShell:

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

假设查到 PID 为 1234,继续核对进程名称与路径。1234 只是示例,执行时必须换成刚查到的数字:

tasklist /FI "PID eq 1234"
Get-Process -Id 1234 | Select-Object Id, ProcessName, Path

确认来源后再退出程序

  1. 如果属于另一款代理客户端,从该客户端托盘菜单选择「退出」,不要只关闭主窗口。
  2. 如果属于当前客户端的旧内核,先正常退出当前客户端,再查一次 PID,确认后台进程是否仍然存在。
  3. 如果属于其他业务软件,保留该程序运行,改用空闲的代理端口。
  4. 如果 PID 对应服务或系统进程,先检查「任务管理器」→「详细信息」及「服务」,不要直接强制终止。

进程名里出现 mihomo 或 clash,不代表它一定是残留进程。启用服务模式的客户端可能让内核持续在后台运行。只结束进程而不处理托盘程序或服务,内核也可能立即被重新拉起。

macOS 与 Linux:用 lsof、ss 查监听来源

macOS:区分主窗口与菜单栏进程

打开「应用程序」→「实用工具」→「终端」,查询 TCP 7890 的监听者:

lsof -nP -iTCP:7890 -sTCP:LISTEN

-nP 保留数字地址与端口,避免名称解析影响阅读。输出中的 COMMAND、PID 和 NAME 分别用于识别进程、进程编号与监听地址。若普通查询没有结果但错误仍在,可用 sudo lsof -nP -iTCP:7890 -sTCP:LISTEN 检查其他用户拥有的进程。

确认来源后,从菜单栏图标退出对应客户端。macOS 关闭窗口通常不等于退出应用。需要进一步查看某个 PID 的启动命令时,可执行:

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

Linux:同时检查桌面客户端与服务

多数 Linux 发行版可用 ss 查询;显示完整进程信息时通常需要提权:

sudo ss -ltnp 'sport = :7890'

如果查到的内核来自 systemd 服务,关闭桌面窗口不会停止该服务。先根据输出的进程路径确认归属,再到对应服务管理位置停止重复实例。服务名称取决于安装方式,不能直接把网上某个服务名当作本机名称。

  • 127.0.0.1:7890 表示 IPv4 本机回环监听。
  • 0.0.0.0:7890 表示监听所有 IPv4 接口,可能与只绑定回环地址的实例发生冲突。
  • [::]:7890 表示 IPv6 通配地址;是否同时接受 IPv4,取决于系统与套接字设置。

因此,排查时不能只找文字完全等于 127.0.0.1:7890 的行。通配地址、IPv6 监听和其他用户运行的服务也要纳入检查。

修改 mixed-port:以实际生效配置为准

确认占用者后,有两种处理方式:退出不需要的重复实例,继续使用 7890;或者保留现有程序,把当前客户端改到空闲端口。先用前面的命令检查 17890,再进行修改。下面的配置面向支持这些字段的 Clash 内核及 Clash Meta(mihomo),不是完整订阅文件。

优先修改客户端管理的端口设置

  1. 记录当前混合端口、HTTP 端口、SOCKS 端口及控制接口地址,保存当前配置副本。
  2. 打开客户端「设置」,查找「端口」或「混合端口」。某些客户端会放在「Clash 设置」或「内核设置」下,菜单名称随客户端变化。
  3. 把混合端口改为 17890,保存后执行客户端提供的重启内核操作。
  4. 重新打开日志,确认新监听成功,再用系统命令检查 17890 的占用者是否为预期内核。

若客户端通过 YAML 管理这些值,可在它实际采用的本地配置或覆写配置中修改:

# 合并到现有配置中,不要用此片段覆盖完整配置。
mixed-port: 17890
allow-lan: false

allow-lan: false 用于限制局域网接入场景,不是解除占用的开关。仅供本机使用时,不要为了排错把监听地址改为 0.0.0.0,也不要随意开启局域网访问。

检查旧入口与覆写来源

配置可能同时定义 port、socks-port 与 mixed-port。修改混合端口不会自动移除另外两个入口;如果报错来自其他监听项,仍需分别处理。不要在同一个 YAML 映射中重复添加多个 mixed-port 键。

订阅文件还可能被客户端的全局设置、合并配置或覆写规则覆盖。直接编辑下载得到的订阅,下次更新后可能恢复原值。应使用客户端支持的持久化设置,并以启动日志和系统监听结果判断最终值,不能只看编辑器里保存了什么。

9090 冲突:单独处理外部控制端口

如果日志明确指向 9090,应查询 9090 的占用进程,而不是反复修改混合端口。控制接口用于客户端或面板管理内核,不是供浏览器访问网页的 HTTP 代理入口。

# 仅在客户端允许自定义控制接口时合并此项。
external-controller: 127.0.0.1:19090

某些桌面客户端自动管理控制地址与认证信息。应优先在客户端提供的设置入口修改;强行改动生成的配置,可能造成主界面无法连接内核。手动连接的外部面板则需要把控制地址同步为 127.0.0.1:19090,并保持认证密钥匹配。

同步系统代理、终端变量和应用内代理

新端口监听成功后,应用仍访问旧端口是最常见的后续问题。此时日志可能不再报绑定失败,但浏览器会显示代理连接失败,终端也可能出现 connection refused。要逐项检查代理的使用方。

系统代理:确认写入的是 17890

  • Windows 11:打开「设置」→「网络和 Internet」→「代理」→「手动设置代理」→「编辑」,核对地址与端口。使用客户端接管时,通常先关闭再开启客户端的「系统代理」,使其重新写入。
  • macOS:打开「系统设置」→「网络」→ 当前网络服务 →「详细信息」→「代理」,检查网页代理、安全网页代理及 SOCKS 代理中实际启用的项目。
  • 应用内代理:浏览器代理扩展、开发工具和下载工具可能使用独立设置。将手动填写的 127.0.0.1:7890 改成 127.0.0.1:17890。

使用自动代理配置脚本(PAC)时,代理目标可能由脚本返回,而不是来自手动代理栏。应检查当前代理来源,避免同时启用扩展接管与手动系统代理却只修改其中一处。

终端:环境变量不会自动跟随客户端变化

PowerShell 可用以下命令临时更新当前窗口的 HTTP 与 HTTPS 代理。这里的 HTTPS 变量仍使用 http://,因为它指定的是本地 HTTP 代理入口,通过 CONNECT 转发 HTTPS 请求。

$env:HTTP_PROXY = "http://127.0.0.1:17890"
$env:HTTPS_PROXY = "http://127.0.0.1:17890"

macOS 或 Linux 的 sh、bash、zsh 可在当前终端执行:

export http_proxy=http://127.0.0.1:17890
export https_proxy=http://127.0.0.1:17890

还要检查大小写形式的代理变量及 ALL_PROXY、all_proxy,不同工具的优先级并不一致。若配置写在 shell 启动文件、系统环境变量或工具自身配置中,也要更新持久化位置。临时命令只影响当前进程及其后续子进程,不会修改已经打开的其他终端。

TUN 模式处理的是另一条流量接管路径。开启 TUN 不会释放 7890,也不会让一个绑定失败的混合端口恢复监听。排查本地端口时,不要把开关 TUN 当作替代处理。

验证修复:监听、代理请求与重启后配置

验证分三步进行,避免把节点不可达误判为端口仍被占用。下面是检查命令,不预设响应状态或耗时。

  1. 确认监听。把前面的查询命令中 7890 换成 17890,确认 PID 和进程路径属于当前客户端。
  2. 显式指定代理。绕开系统代理自动配置,直接测试本地新端口。
  3. 重新启动验证。正常退出并重新打开客户端,确认端口没有被订阅或覆写恢复,然后再测试浏览器和常用终端工具。

Windows 使用 curl.exe,避免某些 PowerShell 环境中 curl 别名带来的参数差异:

curl.exe --noproxy "" --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 20 -I https://clash15.com/

macOS 与 Linux 可使用:

curl --noproxy "" --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 20 -I https://clash15.com/

--noproxy "" 用于避免现有绕过列表让此次测试直连。收到目标站响应可用于判断这次请求路径,但不能证明所有节点和规则都正常。如果仍报本地连接被拒绝,先回查监听;如果请求已进入内核日志,之后才出现 DNS 或远端超时,则应转向对应的解析、规则或节点排查。

没有监听者,却仍提示端口无法绑定

先在报错发生的同时重新查询,排除后台实例短暂重启。Windows 若报告访问权限类错误,可检查系统排除的 TCP 端口范围:

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

若目标端口落在排除范围内,优先改用范围外的空闲端口,不要直接删除系统保留项。虚拟化与网络组件可能依赖这些范围。最终应达到四个结果:只有预期实例监听目标端口、启动日志不再报绑定失败、应用使用新端口、客户端重启后配置仍保留。

需要继续检查系统代理与模式选择,可查看系统代理设置步骤;请求已经进入内核但发生远端超时,可转到连接超时排查。端口问题应先在本机解决,再检查订阅和线路。

Clash 安装包下载