Clash 启动报端口被占用怎么办:定位占用进程与修改端口全流程

7890/9090 端口冲突是 Clash 启动失败的高频原因。给出 Windows、macOS、Linux 三平台查占用进程的命令,以及在配置文件与客户端里安全改端口的完整步骤。

为什么会出现"端口被占用"报错

Clash 内核启动时需要绑定几个固定端口才能对外提供代理服务:混合代理端口(通常是 7890,配置字段名为 mixed-port,老版本可能拆成 portsocks-port)、外部控制器端口(通常是 9090,字段名 external-controller),部分客户端还会额外占用一个 DNS 监听端口。这些端口一旦被系统里其他进程提前占用,操作系统会拒绝再次绑定,内核在日志里报出"address already in use""bind: 端口已被使用"之类的字样,客户端表现为启动按钮点击后立刻回弹、连接状态一直显示未连接,或者干脆弹出错误弹窗。

造成占用的来源大致分三类。第一类是"重复启动":同一台电脑上装了两个 Clash 类客户端(比如同时装了 Clash Verge 和 Clash for Windows 的历史遗留版本),或者上一次退出没有彻底结束进程,后台仍挂着一个僵尸实例占着端口。第二类是"端口撞车":其他工具恰好也用了 7890 或 9090,常见的有部分开发调试代理、企业 VPN 客户端、路由测试工具,甚至某些数据库或消息队列服务默认端口也可能落在临近区间。第三类是系统层面的端口保留,尤其在 Windows 上,某些系统服务会预留一段端口区间,恰好把 7890 圈进去,这种情况在任务管理器里往往看不到直接对应的进程名。

排查思路统一分两步:先确认到底是谁占用了端口,再决定"关掉占用者"还是"给 Clash 换端口"。多数场景下改端口更省事,因为不需要动其他软件的配置,风险也更低。

Windows 下定位占用进程

打开命令提示符或 PowerShell,先用 netstat 查看端口对应的进程 ID(PID):

netstat -ano | findstr "7890"

输出的最后一列数字就是 PID,再用任务管理器或下面的命令反查进程名:

tasklist | findstr "PID号"

如果 9090 端口也报冲突,把命令里的端口号换成 9090 再查一次即可。确认是无关进程占用后,可以直接结束该进程,或者打开该软件的设置改掉它自己的端口;如果查出来的进程正是 Clash 自身的历史实例(比如 clash-verge.exemihomo.exe 挂了一个后台残留),在任务管理器里手动结束该进程后重新启动客户端通常就能解决。

注意:部分安全软件或系统保留端口范围会让 netstat 查不到具体进程(PID 显示为 0 或系统进程),这种情况直接改 Clash 自己的端口最省时间,不必纠结找出占用者。

macOS 下定位占用进程

打开终端,用 lsof 查看端口占用情况最直接:

lsof -i :7890

输出里 COMMAND 列就是占用该端口的进程名,PID 列是进程号。9090 端口同理替换数字即可。如果要结束占用进程:

kill -9 对应的PID号

macOS 上比较常见的情况是同时安装了 Clash Verge 与旧版 ClashX 系列客户端,两者默认端口一致,只要有一个在后台常驻(比如设置了登录时启动),另一个再启动就会冲突。建议在系统设置的登录项里检查一遍,只保留一个默认开机自启的客户端。

Linux 下定位占用进程

Linux 系统推荐用 ss 命令(比传统 netstat 更快、多数现代发行版默认自带):

ss -tulnp | grep 7890

如果系统没有 ss,可以退回用 netstatlsof:

lsof -i :7890

确认进程 PID 后用 kill 结束:

kill -9 对应的PID号

用命令行核心(mihomo/Clash 内核)配合 systemd 管理服务的用户要特别留意:如果内核是通过 systemd 单元文件启动的,直接 kill 掉进程之后 systemd 可能会按重启策略自动把它拉起来、再次占住端口,这种情况下应该先用 systemctl stop 停掉对应服务单元,确认端口释放后再排查冲突根源,而不是反复 kill。

在配置文件里修改端口

如果确认端口被无法关闭的其他程序占用,最干净的做法是给 Clash 换一个端口,而不是折腾对方软件。核心配置字段集中在 config.yaml 顶部:

mixed-port: 7891
allow-lan: false
external-controller: 127.0.0.1:9091
secret: ""

mixed-port 改成一个空闲端口(建议选 1024~65535 区间内、不与常见服务冲突的数字,比如 7891、17890 均可),external-controller 后面的端口号同理修改,注意这里是"地址:端口"的完整写法,不要漏掉冒号前的监听地址。部分较旧配置文件仍用分离的 port(HTTP 代理端口)与 socks-port(SOCKS5 代理端口)两个字段而不是合并的 mixed-port,同样按需改成空闲数字即可,原理一致。

提示:改完端口后需要重启客户端或重新加载配置才会生效,单纯保存 YAML 文件、内核不重启是不会自动生效的。

在客户端界面里修改端口

如果不想直接编辑 YAML,主流客户端都在设置界面提供了端口输入框,路径大致如下:

  1. 打开客户端设置

    找到"设置"或"常规"分类,定位到"混合端口""HTTP 端口""SOCKS 端口"或"代理端口"字样的输入项。

  2. 填入新端口号

    填入一个确认未被占用的端口号,建议先用前面的命令验证一遍该端口当前处于空闲状态。

  3. 同步修改控制端口

    如果客户端还单独列出了"外部控制端口"或"API 端口"(对应 external-controller),也一并改成空闲值,两者不冲突即可。

  4. 保存并重启服务

    保存设置后,客户端通常会提示重启内核或重启应用才能生效,按提示操作即可,不要在提示重启前反复点击连接按钮。

  5. 核对系统代理设置

    如果系统的网络代理设置里手动填写过端口号(而非跟随客户端自动配置),记得把系统代理里的端口号也同步改成新值,否则流量仍会指向旧端口导致连接失败。

改完端口后如何验证生效

重启客户端后,先用命令行确认新端口已经处于监听状态,而不是直接打开浏览器测试(浏览器测试受系统代理设置、DNS 缓存等因素干扰,不够直接)。Windows 下继续用 netstat -ano | findstr "新端口号",能看到 LISTENING 状态即表示内核已经成功绑定。macOS 和 Linux 下用 lsof -i :新端口号,能查到对应的 Clash 内核进程名(常见为 mihomoclash-meta 或客户端自带的内核可执行文件名)即为正常。

确认监听正常后,再检查系统代理或浏览器插件里填写的端口号是否与新端口一致,两端对齐才能真正连通。如果用的是控制面板类客户端自带的"测试连接"或"延迟检测"功能,此时应该能正常返回结果,不再报连接被拒绝。

预防端口冲突的几个习惯

为了减少下次再遇到同样问题,可以养成几个小习惯:一是同一台设备尽量只保留一个 Clash 类客户端,升级新版本前先卸载或完全退出旧版本,避免两者常驻后台互相打架;二是如果电脑上还跑着别的代理工具或需要固定使用某些端口的开发环境,提前把 Clash 的端口设成一个明显不常用的数字(比如五位数的高位端口),从源头上避开撞车;三是每次修改端口配置后,顺手记一下改成了什么值,方便下次排查时对照,尤其是团队共用配置文件的场景,端口号变动最好在配置文件头部加一行注释说明。

如果端口冲突反复出现在同一个程序上(比如某个固定安装的企业软件长期占着 9090),更彻底的做法是直接把 Clash 的默认端口永久改掉,而不是每次都临时腾位置,这样配置文件和客户端设置只需要改一次,长期使用不会再被打断。

下载客户端