Clash Verge 端口冲突报错 7890 / 9090 怎么办?端口占用排查与修改指南

全网最深度硬核的 Clash Verge Rev 端口冲突排查白皮书。深入推演 TCP 套接字独占绑定、Hyper-V/WSL2 动态保留端口黑洞、netstat 进程追踪技术,提供 8 大极端场景自愈与自动化一键排查脚本。

一句话答案:Clash Verge 启动提示 “listen tcp 127.0.0.1:7890: bind: address already in use”,核心根因在于后台残留的旧版代理(如 CFW、v2rayN)僵尸进程占用了 7890 混合端口、本地运维工具占用了 9090 控制器端口,或 Windows Hyper-V 动态保留端口段恰好覆盖了该端口。通过 netstat 查找 PID 强杀进程,或在设置中将混合端口直接修改为 7897/17890,即可 100% 极速自愈。

本文要点

  1. 核心要点:TCP/IP 协议规范要求同一 IP 地址上的同一端口在同一时间只能被单个进程独占绑定。
  2. 核心要点:7890 为混合代理端口 (Mixed Port),9090 为外部控制器 RESTful API 端口。
  3. 核心要点:Hyper-V 和 WSL2 重启后会随机随机保留数千个端口,将端口修改为高位段可永久避坑。
  4. 核心要点:修改端口后,终端 Git、Docker 以及浏览器 SwitchyOmega 插件必须同步更新端口号。

一、TCP/IP 套接字独占机制:操作系统为何拒绝端口绑定

在网络编程规范与 TCP/IP 体系中,操作系统使用 套接字(Socket) 作为网络通信的端点。一个网络监听套接字由一个四元组唯一标识:(协议, 本地 IP, 本地端口, 远程 IP, 远程端口)。

当 Clash Verge Rev 的底层核心(Mihomo)尝试提供代理入站服务时,它必须向操作系统内核发起 socket() 创建与 bind() 端口绑定系统调用:

+-----------------------------------------------------------------------------------+
|                        TCP 套接字独占绑定与端口冲突裁决流程图                         |
+-----------------------------------------------------------------------------------+
                                         │
             [Mihomo 启动并请求 bind(AF_INET, SOCK_STREAM, 7890)]
                                         │
                                         ▼
                     +---------------------------------------+
                     |    Windows 内核套接字管理器 (Winsock)   |
                     |  检查端口 7890 当前占用状态与绑定安全标志 |
                     +---------------------------------------+
                                         │
                     ┌───────────────────┴───────────────────┐
                     │                                       │
            【端口已被其他进程独占绑定】               【端口处于绝对空闲状态】
                     │                                       │
                     ▼                                       ▼
        +-------------------------+             +-------------------------+
        |   返回 WSAEADDRINUSE    |             |   返回 0 (绑定成功)      |
        |   内核抛出 Listen Error  |             |   进入 listen() 监听队列 |
        +-------------------------+             +-------------------------+
                     │                                       │
                     ▼                                       ▼
         [Clash Verge 界面弹窗报警]                 [本地 7890 正常接管代理流量]

Windows 和大多数现代操作系统为了防止网络劫持,默认启用或强化了 SO_EXCLUSIVEADDRUSE 套接字安全选项:

  • 如果一个进程已经成功在 127.0.0.1:7890 或全局 0.0.0.0:7890 上建立了 LISTEN 状态,任何后续进程再次请求绑定完全相同的 IP 与端口时,内核会直接返回错误代码 WSAEADDRINUSE (10048)(即 Address already in use)。
  • 这意味着操作系统从物理底层杜绝了“两个不同软件同时共享同一端口接收流量”的可能性。Mihomo 内核在捕获到该底层错误后无法继续拉起服务,只能被迫向 UI 抛出错误并终止。

二、常见端口冲突根因与全息排障矩阵

下表总结了 Clash Verge Rev 运行中最常见的端口冲突来源及其技术特征:

冲突端口号默认核心功能典型占用进程 / 冲突来源严重级别推荐解决路径
7890混合代理端口 (Mixed Port)残留的 Clash for Windows、v2rayN、老旧代理服务极高 (导致代理全盘瘫痪)强杀残留进程,或将端口改至 7897 / 17890
9090外部控制器 RESTful APIPrometheus、Cockpit、本地 Go/Node.js 开发服务高 (导致 UI 无法连通内核)在设置中修改外部控制端口至 9097
7897现代 Verge 备选混合端口其他开机自启的现代客户端 (如 Mihomo Party)高避免同时开机运行多个代理客户端
1080SOCKS5 代理端口旧版 Shadowsocks-libev、系统 SOCKS 服务中停用旧版工具,全部交由 Mihomo 托管
53 / 1053本地 DNS 监听端口Windows Internet 连接共享 (ICS)、AdGuard Home极高 (导致 DNS 模块崩溃)关闭 Windows ICS 服务或修改 DNS 监听端口
动态段随机高位端口Hyper-V / WSL2 动态保留端口黑洞隐蔽 (netstat 查不到具体进程)调整 Windows 动态保留端口起始范围

三、实战排障:8 大极端边界冲突场景深度归因与自愈操作

场景 1:老版 Clash for Windows (CFW) 僵尸进程死锁 7890 端口

  • 故障现象:双击 Clash Verge Rev 提示 listen tcp 127.0.0.1:7890: bind: address already in use。桌面上明明没有打开任何其他软件。
  • 底层归因:用户此前电脑上安装了老版 CFW。在切换到 Verge 之前,用户虽然点击了 CFW 窗口的关闭按钮,但老版 CFW 默认仅仅是“最小化到托盘”;即使用户通过任务管理器强行关闭了主窗口,CFW 注册在系统后台的后台服务 clash-core-service 依然作为独立进程在后台持续运行,死死咬住 7890 端口。
  • 精准解决步骤:
    1. 打开任务管理器(Ctrl + Shift + Esc),切换到“服务”选项卡。
    2. 寻找名为 Clash Core Service 或 clash-core-service 的服务。
    3. 鼠标右键点击并选择“停止”;接着按下 Win + R 输入 services.msc,双击该服务将“启动类型”改为“禁用”。
    4. 重新启动 Clash Verge 即可秒级恢复。

场景 2:9090 外部控制器端口被本地监控或开发服务占用

  • 故障现象:客户端可以正常打开,但顶部或底部常态化弹窗提示 Failed to connect to external controller: 127.0.0.1:9090,且节点测速全部显示为 0。
  • 底层归因:9090 是开源监控体系 Prometheus(普罗米修斯) 以及 Linux Web 管理后台 Cockpit 的默认服务端口。如果你是全栈工程师或在本地部署了 Docker 监控全家桶,Prometheus 会抢先霸占 9090 端口,导致 Mihomo 无法拉起 RESTful API 服务器,前端 UI 无法向核心发送控制指令。
  • 精准解决步骤:
    1. 进入 Clash Verge 的“设置”页面。
    2. 找到“外部控制”或“控制器端口”设置项,将默认的 9090 修改为一个完全冷门的高位端口(如 9097 或 29090)。
    3. 点击“重启内核”,前端 UI 会立即以新端口与核心重新建立握手,故障瞬间消解。

场景 3:Windows 11 Hyper-V / WSL2 动态保留端口黑洞

  • 故障现象:执行 netstat -ano | findstr 7890 没有任何输出,任务管理器里没有任何软件在占用该端口,但 Clash Verge 启动依然报错“端口已被占用”!
  • 底层归因:这是 Windows 虚拟化架构(Hyper-V / WSL2)广为人知的“幽灵黑洞”。为了给内部容器分配网络,Windows 在每次开机时会从系统动态端口池中随机划出数个连续的端口范围。如果开机时分配算法恰好将 7890 划入了保留范围,Winsock 内核就会对该端口实施无条件保留,导致普通应用根本无法绑定。
  • 精准解决步骤:
    1. 在管理员 PowerShell 中运行命令验证:netsh int ipv4 show excludedportrange tcp,查看 7890 是否落在某个被排除的端口区间内。
    2. 永久根治方案:通过注册表为 Windows 指定专用的动态端口起始范围,避开常用端口。在管理员终端执行:
      netsh int ipv4 set dynamicport tcp start=49152 num=16384
      
    3. 或者直接在 Clash Verge 中将混合代理端口修改为高位端口 17890,彻底跳出 Hyper-V 的随机覆盖区。

场景 4:多代理客户端(v2rayN 与 Clash Verge)同时开机自启争抢

  • 故障现象:电脑开机后有时 Clash Verge 能正常联网,有时却报错无法启动,具有明显的随机性。
  • 底层归因:用户电脑的开机自启列表中同时勾选了 v2rayN 和 Clash Verge Rev。操作系统在启动应用时具有微秒级的时序不确定性。哪一个客户端先启动,哪一个就抢先霸占了 1080 / 7890 端口;后拉起的那一个必然会因端口已被占用而崩溃。
  • 精准解决步骤:
    1. 统一客户端选型:建议日常主力只保留一个客户端开机自启。
    2. 打开任务管理器 ->“启动应用”,禁用多余代理客户端的开机自启开关。

场景 5:执行 taskkill 强杀进程提示“错误: 拒绝访问”

  • 故障现象:在 CMD 或终端中执行 taskkill /F /PID 1234 时,系统报错 错误: 无法终止 PID 为 1234 的进程。原因: 拒绝访问。
  • 底层归因:该占用进程是以最高管理员(Administrator)甚至系统服务(SYSTEM)身份启动的,而当前打开的命令行窗口仅仅具有受限的标准用户权限。
  • 精准解决步骤: 按下 Win + S 搜索“PowerShell”,在右侧点击“以管理员身份运行”。再次执行 Stop-Process -Id 1234 -Force 即可凭借最高特权强行回收套接字。

场景 6:修改端口为 7897 后外部开发工具网络报错全断

  • 故障现象:用户在 Clash Verge 设置中将端口成功改为了 7897,软件不再报错了;但随后在终端中执行 git clone、npm install 或使用 Postman 时,全部报错 Proxy connection refused。
  • 底层归因:开发者的全局环境变量(如 HTTP_PROXY、HTTPS_PROXY)或 Git 全局配置依然硬编码指向了旧的 http://127.0.0.1:7890。由于 7890 已经没有服务在监听,外部工具的所有网络请求全部撞墙。
  • 精准解决步骤:
    1. 更新 Git 代理配置:
      git config --global http.proxy http://127.0.0.1:7897
      git config --global https.proxy http://127.0.0.1:7897
      
    2. 检查环境变量:在系统属性中将 HTTP_PROXY 对应的值同步修正为 7897。

场景 7:局域网共享模式(Allow LAN)开启后外网设备连接失败

  • 故障现象:开启了“允许局域网连接”,但在同局域网的手机上配置该电脑的 IP 和 7890 端口,手机依然无法上网,提示连接超时。
  • 底层归因:Mihomo 内核虽然成功监听了 0.0.0.0:7890,但 Windows 防火墙(Windows Defender Firewall)的高级安全规则默认拦截了来自非本机 IP 的外部 TCP 入站连接。
  • 精准解决步骤: 在管理员 PowerShell 中运行以下命令,为 Clash Verge 添加入站防火墙白名单:
    New-NetFirewallRule -DisplayName "Clash Verge Mixed Port" -Direction Inbound -LocalPort 7890,7897 -Protocol TCP -Action Allow
    

场景 8:DNS 监听端口 53 冲突导致内核全盘闪退

  • 故障现象:在配置中开启了本地 DNS 监听后,核心闪退报错 listen udp 127.0.0.1:53: bind: permission denied / address already in use。
  • 底层归因:53 是标准的系统 DNS 端口。Windows 系统的“Internet 连接共享服务(SharedAccess)”默认霸占了本地 53 端口;在 Linux 系统中 systemd-resolved 也会常驻监听 127.0.0.53:53。
  • 精准解决步骤: 不要强求 Mihomo 监听 53 端口!在配置的 dns: 模块中将 listen: 设置为非标准端口(如 0.0.0.0:1053),或者依靠 TUN 模式进行透明重定向,即可完美绕开 53 端口冲突。

四、场景化决策选型卡片

合理规划本地开发环境与网络服务体系:

::: tip 💡 端口规划黄金准则 在复杂的工程生产力环境中,绝不要将所有网络服务堆叠在 7890 和 9090 这类大众通用端口上。建议资深开发者在首次配置 Clash Verge Rev 时,主动将混合代理端口自定义为高位端口(如 7897 或 17890),将外部控制器端口自定义为 9097。这能让你从物理上 100% 免疫未来所有潜在的第三方软件冲突与 Hyper-V 保留黑洞。 :::

::: warning ⚠️ 区分本地端口冲突与远端专线阻断 很多技术人员在遇到网络连接超时时,往往首先怀疑是本地端口被占用了;但当通过排查确认端口监听完全正常后,才发现是低质公共节点发生了大面积封锁、境外落地机房断流!
为了保障关键业务与远程生产力绝不中断,常备一套高质量的物理专线(IPLC / IEPL)服务是专业工程团队的标准实践:

佣金与商业合规披露声明:本站所收录或提及的部分网络服务包含推广导流链接;通过相关链接注册可能会为本站带来一定的运维佣金,但这绝不会对您的实际订购价格产生任何影响。本站始终坚守独立客观的技术评测底线。请使用者严格遵守中华人民共和国网络安全法律法规,文明合法使用网络资源。


五、自动化端口占用排查与一键强杀脚本

以下由 ClashNet 技术实验室精心编写的自动化排障脚本,支持毫秒级定位占用 7890/9090 的流氓进程并执行一键精准清理:

Windows 自动化端口排查与强杀脚本 (PowerShell)

# ==============================================================================
# ClashNet 官方出品:端口冲突排查与僵尸进程一键强杀工具 (PowerShell)
# 请使用管理员身份打开 PowerShell 运行
# ==============================================================================
Write-Host "==========================================================" -ForegroundColor Cyan
Write-Host "   Clash Verge 端口占用分析与自动化一键清理工具" -ForegroundColor Cyan
Write-Host "==========================================================" -ForegroundColor Cyan

$targetPorts = @(7890, 7897, 9090, 1080)

foreach ($port in $targetPorts) {
    Write-Host "`n[*] 正在扫描端口 [$port] 状态..." -ForegroundColor Yellow
    $connections = Get-NetTCPConnection -LocalPort $port -State Listen -ErrorAction SilentlyContinue

    if ($connections) {
        foreach ($conn in $connections) {
            $pidNum = $conn.OwningProcess
            $proc = Get-Process -Id $pidNum -ErrorAction SilentlyContinue
            $procName = if ($proc) { $proc.ProcessName } else { "未知系统进程" }
            $procPath = if ($proc) { $proc.Path } else { "未知路径" }

            Write-Host "  [-] 警告:端口 [$port] 正在被监听!" -ForegroundColor Red
            Write-Host "      进程 PID   : $pidNum" -ForegroundColor Cyan
            Write-Host "      进程名称   : $procName" -ForegroundColor Cyan
            Write-Host "      可执行路径 : $procPath" -ForegroundColor Gray

            # 提示是否强杀
            $choice = Read-Host "  -> 是否强杀该进程并释放端口 $port ? (y/n)"
            if ($choice -eq 'y' -or $choice -eq 'Y') {
                Stop-Process -Id $pidNum -Force -ErrorAction SilentlyContinue
                Write-Host "  [+] 已成功强制终止进程 PID: $pidNum,端口已释放!" -ForegroundColor Green
            }
        }
    } else {
        Write-Host "  [+] 端口 [$port] 状态正常:完全空闲,无任何进程占用。" -ForegroundColor Green
    }
}

Write-Host "`n[*] 正在查询 Windows Hyper-V 动态保留端口范围..." -ForegroundColor Yellow
$excluded = netsh int ipv4 show excludedportrange tcp | Out-String
if ($excluded -match "7890") {
    Write-Host "  [-] 严重提示:端口 7890 当前正处于 Hyper-V 排除保留列表中!建议将 Verge 端口修改为 7897 或 17890。" -ForegroundColor Red
} else {
    Write-Host "  [+] 7890 未被 Hyper-V 保留,环境安全。" -ForegroundColor Green
}

Write-Host "`n==========================================================" -ForegroundColor Cyan
Write-Host "   排查流程执行完毕!" -ForegroundColor Green
Write-Host "==========================================================" -ForegroundColor Cyan

macOS / Linux 终端端口排查与清理命令 (Bash)

#!/usr/bin/env bash
# ==============================================================================
# ClashNet 官方出品:macOS / Linux 端口占用排查与清理脚本
# ==============================================================================
PORTS=(7890 7897 9090)

for port in "${PORTS[@]}"; do
    echo -e "\x1b[36m=== 检查端口: $port ===\x1b[0m"
    PID=$(lsof -ti :$port)
    if [ -n "$PID" ]; then
        PROC=$(ps -p $PID -o comm=)
        echo -e "\x1b[31m[-] 端口 $port 被进程 $PROC (PID: $PID) 占用!\x1b[0m"
        read -p "是否立即终止该进程以释放端口?(y/n): " confirm
        if [ "$confirm" = "y" ]; then
            kill -9 $PID && echo -e "\x1b[32m[+] 已成功终止 PID: $PID\x1b[0m"
        fi
    else
        echo -e "\x1b[32m[+] 端口 $port 处于空闲状态。\x1b[0m"
    fi
done

六、长尾技术深度常见问答 (FAQ)

Q1:修改了 7890 混合端口后,以前配置的 Git 命令行和浏览器插件会失效吗?

会失效!如果此前你在终端执行过 git config --global http.proxy http://127.0.0.1:7890,或者在 Chrome 的 SwitchyOmega 插件中配置了 127.0.0.1:7890,一旦你将 Clash Verge 的端口修改为了 7897,那些外部程序向 7890 发起的请求都会被系统直接拒绝(Connection Refused)。你必须同步更新外部程序的代理端口配置。

Q2:为什么提示 9090 端口被占用?这个端口不是代理端口吧?

9090 是 Mihomo 内核的外部控制器(External Controller)API 端口,而不是传输代理数据的端口。前端图形界面(UI)需要通过访问 http://127.0.0.1:9090 来实时获取节点延迟、切换分流策略并拉取流量图表。在设置的“外部控制”中将其修改为 9097 或 19090 即可轻松解决冲突。

Q3:在 PowerShell 中使用 taskkill /F /PID 强杀进程提示“拒绝访问”怎么办?

这表明占用该端口的进程是以更高的系统级权限(如 NT AUTHORITY\SYSTEM)或 Windows 服务模式运行的,标准用户权限的终端无权终止它。必须以鼠标右键点击“终端”并选择“以管理员身份运行”,再次执行终止命令;或者进入 services.msc 找到对应的系统服务手动停止。

Q4:什么是 Windows 的 Hyper-V / WSL2 动态保留端口黑洞?

Windows 开启 Hyper-V、WSL2 或沙盒后,系统在开机阶段会为容器网络驱动动态预留多个连续的端口段(通常为 1000 个端口一段)。由于这些端口是内核网络栈预先锁定的,netstat 甚至查不到任何占用进程,但普通程序调用 bind() 时系统直接报错。遇到这种情况,通过 netsh int ipv4 show excludedportrange tcp 可以查看被排除的端口范围。

Q5:为什么我已经把老版 Clash for Windows 关掉了,任务管理器里也没有,还是提示占用?

因为老版 CFW 的“系统服务(Clash Core Service)”并没有随主界面退出而停止!老版 CFW 会在后台常驻一个名为 clash-core-service 的 Windows 系统服务,这个服务依然在静默监听 7890 端口。按下 Win + R 输入 services.msc,找到该服务右键点击“停止”并将其启动类型设置为“禁用”。

Q6:Clash Verge 支持将端口绑定在 0.0.0.0 吗?有安全风险吗?

当开启“允许局域网连接(Allow LAN)”时,Mihomo 会自动将监听地址从 127.0.0.1 扩展至 0.0.0.0:7890。这允许手机、电视等同局域网设备共享代理;但在公共 Wi-Fi(如咖啡厅、机场公共网络)环境下,任何人都能探测到你的开放端口并白嫖甚至扫描你的本地服务。在公共网络下建议关闭 Allow LAN,或设置高强度认证密码(Secret)。

Q7:在 macOS / Linux 下,端口被占用怎么查?

在终端中直接运行命令 lsof -i :7890 或 sudo netstat -tulpn | grep 7890。命令会清晰打印出占用进程的名称(COMMAND)和进程 ID(PID)。随后执行 kill -9 <PID> 即可瞬间清理。

Q8:为什么有时候把端口改成了 1080,提示由于权限无法启动?

在 Linux 和 macOS 系统中,小于 1024 的端口属于“特权端口(Privileged Ports)”,必须具备 root 超级用户权限才能绑定。虽然 1080 大于 1024,但 1080 是标准的 SOCKS 历史保留端口,极易与系统已有的 socks 守护进程冲突。建议日常使用 7890、7897 或 10000 以上的高位非特权端口。


七、知识图谱与延伸学习

数据来源与事实核验: