客户端点了图标没反应,或者启动后一直转圈、任务栏图标闪一下就没了——这类"起不来"的问题,八成都不是软件坏了,而是**它要监听的端口被别的程序占了**。
代理类客户端通常要在一个本地端口上监听(常见 7890、7891、1080 这类),如果那个端口已经有程序在用,新进程绑定失败,表现就是启动即退出,而且很多客户端不会弹错误框。
第一步:确认是不是端口问题
先手动启动一次,看有没有输出。命令行启动最直接:
# macOS / Linux
/Applications/YourApp.app/Contents/MacOS/YourApp
# Windows(在安装目录里)
YourApp.exe
如果看到 bind: address already in use、EADDRINUSE、或者中文的"端口占用",就可以确诊了。
第二步:找到是谁占的
Windows
# 查 7890 端口被谁占了
netstat -ano | findstr :7890
# 最后一列是 PID,用 PID 查进程名
tasklist | findstr 12345
macOS / Linux
# 两种写法都行
lsof -i :7890
ss -lptn 'sport = :7890'
输出里会直接给出进程名和 PID。知道是谁之后,判断就简单了:
| 占用者 | 说明 | 处理 |
|---|---|---|
| 同一个客户端的另一个实例 | 重复启动、托盘里还留着一个 | 退出所有实例再启动 |
| 旧版本残留进程 | 升级后旧进程没退出 | 结束进程,必要时重启 |
| 另一个代理工具 | 两套工具抢同一个端口 | 改端口,或只留一个 |
| 系统进程(Windows 的 SYSTEM) | 系统服务占用 | 换端口,别杀系统进程 |
| 没有进程,但显示占用 | TIME_WAIT 未释放 | 等 1–2 分钟,或换端口 |
第三种情况最容易被误判:TIME_WAIT
有时候 netstat 能看到端口在监听,但 lsof 找不到进程——因为连接已经关闭,只是 TCP 还在 TIME_WAIT 状态,要等 2 倍 MSL(通常 60 秒左右)才释放。
这不是故障,等一会儿就好。但如果你**刚关掉旧实例就立刻启动新的**,就会正好撞上这段窗口期,表现成"昨天还好好的,今天突然起不来"。
第四种:SYSTEM 进程占着不放
Windows 上有时 netstat 显示占用者是 PID 4(SYSTEM)。这种情况通常是系统服务(比如某些安全软件、虚拟化组件)绑定了这个端口。
不要试图结束 PID 4,那是系统进程。正确处理是换一个端口:
- 在客户端设置里把本地监听端口从 7890 改成 7891 或 7897
- 如果有程序手动填过 7890(比如命令行里的
http_proxy),一并改掉 - 重启客户端确认
换端口之后,别忘了这些地方
端口不是只改客户端就完事,下面这些地方也要跟着改,否则会出现"能连上但没网":
- 环境变量:
http_proxy/https_proxy里写死的端口 - git / npm / pip 各自的代理配置
- 浏览器插件(SwitchyOmega 之类)里的代理服务器设置
- 其他软件(Docker、IDE、下载工具)里手动配过的代理
判断口诀
一句话:起不来先看端口,端口先看占用,占用先看是不是自己。
大部分"端口被占用"其实是自己开了两份,或者旧进程没退干净。真正需要换端口的场景不到三成。
💡 一个快速验证:把客户端端口临时改成 17890 再启动。能起来,就确认是端口冲突;起不来,问题在别处(权限、防火墙、安装损坏)。
延伸阅读:连接失败怎么排查、TUN 模式和系统代理、延迟怎么测才准。