先确认监听失败,再决定是否改端口
Clash 提示 7890 端口被占用时,应先查清哪个进程正在监听,再选择退出重复实例或更换监听端口。只改系统代理里的数字,不会改变内核的实际监听位置;只改配置文件而不更新系统代理,也会使浏览器继续连接旧端口。
本文以本机代理地址 127.0.0.1:7890 为起点,以 17890 为替换示例。17890 不是保证空闲的专用端口,使用前仍需查询。Clash、Clash Meta(现称 mihomo)及其图形客户端的默认端口可能不同,应以当前生效配置和启动日志为准。
日志中的错误需要分开处理
| 日志或现象 | 优先检查 |
|---|---|
address already in use | 已有监听进程、重复运行的内核,或配置中多个入站使用同一地址和端口。 |
Only one usage of each socket address | Windows 上常见的地址占用错误,先查本地监听端口和 PID。 |
permission denied 或 access permissions | 权限、安全软件或系统保留端口范围,不应直接判定为另一个软件占用。 |
| 浏览器显示代理连接失败 | 代理地址是否正确、内核是否启动;这一现象本身不能证明端口冲突。 |
先打开客户端日志,记录出错的地址、端口和协议。若日志实际指向 9090,需要检查控制接口,而不是修改 7890。若配置没有启用 mixed-port,则应排查实际使用的 port 或 socks-port。
Windows:用 netstat 定位占用进程
在终端中先检查 TCP 监听。打开 PowerShell 或命令提示符,执行以下命令;若进程信息不完整,再使用管理员权限重试。
netstat -ano -p tcp | findstr ":7890"
查找“本地地址”一列以 :7890 结尾、状态为 LISTENING 的记录。不要把“外部地址”里的 7890 或 TIME_WAIT 连接误当成正在监听的服务。下面是格式示例,不代表当前设备的实际输出:
TCP 127.0.0.1:7890 0.0.0.0:0 LISTENING 6420
末列 6420 是示例进程标识符。将它替换为实际 PID,再查询进程名称:
tasklist /FI "PID eq 6420"
PowerShell 可精确筛选本地端口
如果字符串筛选出现较多结果,可改用下面的命令。没有结果通常表示查询时未发现该 TCP 监听;若命令报权限或其他错误,需要先处理错误,不能据此认定端口空闲。
Get-NetTCPConnection -LocalPort 7890 -State Listen -ErrorAction SilentlyContinue |
Select-Object LocalAddress, LocalPort, OwningProcess
Get-Process -Id 6420 |
Select-Object Id, ProcessName, Path
- 如果是另一个 Clash 客户端,先从其托盘菜单正常退出,并确认后台内核也已停止。
- 如果是同一客户端的旧内核,先关闭客户端,再检查服务模式是否仍在运行。按客户端提供的服务管理入口停止服务,避免反复启动出更多实例。
- 如果是必须保留的开发服务或其他代理程序,让该程序继续使用原端口,为 Clash 选择新的空闲端口。
macOS 与 Linux:用 lsof 检查监听
macOS 可在“终端”中执行 lsof;Linux 如果没有安装该工具,可使用 ss。以下命令只查看 TCP 监听,便于先排查浏览器通过 HTTP 代理建立连接的入口。
sudo lsof -nP -iTCP:7890 -sTCP:LISTEN
-nP 禁止把地址和端口转换成名称,输出中的 COMMAND 是进程名,PID 是进程编号,NAME 是监听地址。可继续检查完整启动命令,区分桌面客户端启动的内核与手工运行的服务:
ps -p 6420 -o pid,ppid,command
Linux 上也可以运行:
sudo ss -ltnp 'sport = :7890'
127.0.0.1:7890 表示 IPv4 回环监听;0.0.0.0:7890 表示监听全部 IPv4 地址。通配地址监听可能与同端口的回环监听冲突。看到 [::]:7890 时,还要考虑系统的 IPv6 双栈行为,不能仅因它不是 IPv4 地址就排除冲突。
需要时补查 UDP
TCP 与 UDP 的端口空间独立。UDP 7890 被占用不等于 TCP 7890 一定无法启动;但在启用了相关 UDP 入站能力时,仍需按日志继续排查。
# macOS / 已安装 lsof 的 Linux
sudo lsof -nP -iUDP:7890
# Linux
sudo ss -lunp 'sport = :7890'
确认进程属于哪项服务后,优先从其应用界面或服务管理器停止。服务受到自动重启管理时,单独结束子进程可能只会触发再次启动,端口很快又被占用。
路径一:在客户端设置中修改端口
图形客户端通常会在启动时生成运行配置。对于这类客户端,应优先使用设置界面修改端口,不要先编辑临时生成的文件。不同客户端与版本的菜单名称并不统一,“设置”中的“端口”“代理端口”或“混合端口”通常是查找入口。
- 先按前面的命令检查 17890,把查询中的
7890替换为17890。 - 记录当前端口和系统代理开关状态。若客户端处于持续启动失败状态,可暂时关闭系统代理,避免应用继续连接不可用入口。
- 打开客户端“设置”,查找“混合端口”或标有
mixed-port的字段,填写17890。不要误改“外部控制”“API”或“控制器端口”。 - 保存设置,按界面提示重载配置或重启内核。仅关闭设置窗口不一定会应用变更。
- 检查日志和系统监听结果,确认 17890 已由目标内核监听,再重新启用系统代理。
如果客户端把“HTTP 端口”和“SOCKS 端口”分开显示,先确认当前是否启用混合端口。不要把三个字段都改成 17890;它们不是三个可以互换的显示名称。无法确认字段含义时,可先阅读配置参考。
路径二:修改 config.yaml 的 mixed-port
直接运行内核或明确使用本地配置时,可以修改实际加载的 YAML 文件。先查看启动参数或客户端显示的配置路径,确认编辑的是生效文件。文件名叫 config.yaml,并不代表它一定正在被使用。
下面是本机使用场景的顶层字段片段。将它合并到现有配置,保留原有节点、策略组和规则;它不是可直接替换完整订阅的配置文件。
mixed-port: 17890
allow-lan: false
mode: rule
log-level: info
mixed-port:同一个监听入口接受 HTTP 代理与 SOCKS 代理连接,应用端仍需选择正确的代理协议。allow-lan: false:适用于仅供本机使用的场景,不要为了修复本地端口冲突随意开启局域网访问。mode: rule:保留规则分流模式。修改入站端口不需要同时改变分流模式。log-level: info:便于查看启动信息;排障结束后可恢复原来的日志级别。
检查重复键与其他入站
字段应位于 YAML 顶层,使用空格缩进,不要放进 proxies 或 proxy-groups。同一层级不要写两次 mixed-port;不同解析器对重复键的处理可能不同,不应依赖“后写覆盖前写”。
还应搜索现有的 port、socks-port 和其他入站监听配置。不要让 port: 17890 与 mixed-port: 17890 同时尝试占用相同 TCP 地址。是否保留独立入站,应由应用实际需求决定。
校验配置后重载
直接使用 mihomo 时,可用内核的配置测试参数检查语法。以下示例假定当前目录中的配置文件就是运行时使用的文件;若实际路径不同,应使用真实路径。
mihomo -t -f ./config.yaml
配置测试通过不等于已经成功监听。保存后还要重载或重启内核,再看启动日志。对于订阅托管的文件,更新订阅可能覆盖手动改动;应使用客户端支持的持久化覆写方式,或把端口交给客户端全局设置管理。
同步修改系统代理与应用代理
内核改为 17890 后,所有仍指向 7890 的代理入口都需要检查。系统代理、浏览器扩展、终端环境变量和开发工具各自保存设置,通常不会一起更新。
| 入口 | 需要确认的值 |
|---|---|
| Windows 11 | “设置”→“网络和 Internet”→“代理”→“手动设置代理”→“使用代理服务器”,地址为 127.0.0.1,端口为 17890。 |
| macOS | “系统设置”→“网络”→当前网络连接→“详细信息”→“代理”,检查网页代理、安全网页代理和已启用的 SOCKS 代理。 |
| 浏览器代理扩展 | 更新当前情景模式中的服务器端口,确认没有继续使用 7890。 |
| 终端与开发工具 | 检查 HTTP_PROXY、HTTPS_PROXY、ALL_PROXY,以及 Git、包管理器和 IDE 的独立代理配置。 |
使用客户端的“系统代理”开关时,可在新端口生效后关闭再开启,并到操作系统设置中复核。macOS 的“安全网页代理”用于 HTTPS 网站的代理连接,名称并不要求本地代理入口本身必须启用 TLS。
如果终端使用环境变量,可在当前 macOS 或 Linux shell 中更新:
export HTTP_PROXY=http://127.0.0.1:17890
export HTTPS_PROXY=http://127.0.0.1:17890
export ALL_PROXY=socks5h://127.0.0.1:17890
这里的 HTTPS_PROXY 仍使用 http://,表示通过本地 HTTP 代理建立连接;socks5h 在支持该写法的工具中表示由代理处理目标域名解析。这些命令只影响当前 shell 及其后续子进程,不会自动写入永久配置,也不是所有工具都读取这些变量。
验证修复结果与持续冲突原因
修复完成至少要确认三件事:新端口确实监听、监听者是预期内核、应用能通过该入口发出请求。先用前面的命令查询 17890,再执行显式指定代理的请求,避免被系统代理或环境变量干扰。
# macOS / Linux
curl -I --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 15 https://example.com/
# Windows PowerShell:显式调用 curl.exe
curl.exe -I --proxy http://127.0.0.1:17890 --connect-timeout 5 --max-time 15 https://example.com/
5 秒是连接超时上限,15 秒是整次请求的时间上限,不是速度测试结果。若出现 Connection refused,优先检查监听地址和内核状态;若代理已接受连接但随后超时,则继续查看规则命中、出站节点和 DNS 日志。收到 HTTP 响应也只说明这次请求经过了入口,不代表所有流量都按预期代理。
端口空闲但仍无法启动
- Windows 保留端口:若日志是访问权限错误且没有监听进程,可执行下方命令查看排除范围。新端口应避开所列范围,不要为此直接删除系统保留项。
- 旧进程自动恢复:检查系统服务、登录启动项,以及是否同时运行两个图形客户端。
- 改错配置文件:核对实际加载路径、启动参数和客户端覆写设置,再比较重载后的日志。
- 虚拟化边界不同:Docker、WSL 和宿主机可能拥有不同的网络命名空间,应在实际绑定端口的一侧检查;容器内监听成功不代表宿主机端口映射成功。
netsh interface ipv4 show excludedportrange protocol=tcp
netsh interface ipv6 show excludedportrange protocol=tcp
开启 TUN 后还要改系统代理吗?
TUN 通过虚拟网卡和路由接管流量,不等同于让应用连接 7890。即便 TUN 仍能工作,配置中启用的混合端口也可能单独绑定失败。反过来,混合端口恢复监听也不能证明 TUN 路由和 DNS 已正常。排障时应把两条接管路径分开验证,不要用“浏览器还能打开网页”代替监听检查。
最后重新启动一次客户端,确认端口设置仍为 17890,再按需测试订阅更新后的配置。若必须恢复为 7890,应先确认原占用者已退出,并将系统代理和应用代理一起恢复。保留排障前后的端口记录,可以减少下次迁移客户端时的重复检查。