问题起因#
之前每次打开 WSL2,顶部都会出现这个提示:
wsl: 检测到 localhost 代理配置,但未镜像到 WSL。NAT 模式下的 WSL 不支持 localhost 代理。text搜索之后,我参考了知乎帖子 ->里的方法,大概率是切换到了 Mirrored 网络模式,或配置了代理镜像。这个代理报错确实立刻解决了。
但新的问题很快出现:在 WSL2 中运行 Java 后端程序时,JMX 端口冲突了。
Error: JMX connector server communication error: service:jmx:rmi://0.0.0.0:26203
jdk.internal.agent.AgentConfigurationError: java.rmi.server.ExportException: Port already in use: 26203; nested exception is:
java.net.BindException: Address already in usetext这就引出了一个问题:WSL2 的 NAT 和 Mirrored 模式到底有什么区别?
先说结论#
- NAT 模式:WSL2 拥有独立的私有网络和端口空间,与 Windows 宿主机的端口互不干扰。即使 Windows 占用了
26203,WSL2 里的 Java 程序仍然可能正常绑定这个端口。 - Mirrored 模式:WSL2 与 Windows 宿主机共享网络接口和端口空间,更接近“同一台设备上的不同进程”。如果 Windows 已经有进程占用
26203,WSL2 再绑定同一端口就会触发Address already in use。
| 对比维度 | NAT 模式 | Mirrored 模式 |
|---|---|---|
| 默认状态 | 默认启用 | 需手动启用(Win11 22H2+) |
| IP 分配 | 私有子网 IP(动态) | 复用宿主机 IP |
| 局域网可达性 | 外部设备无法直接访问 | 外部设备可直接访问 |
| 端口转发 | 需手动配置 | 无需配置(共享宿主机端口) |
| 网络切换适应性 | 较差(切换网络后需重新获取 IP) | 优秀(同步宿主机网络) |
| 性能 | 中等 | 中等 |
| 兼容性 | 最佳(全平台支持) | 有限(仅 Win11 22H2+) |
NAT 模式:默认的网络地址转换#
工作原理#
NAT 是 WSL2 的默认网络模式,基于 Hyper-V 虚拟交换机实现。
Windows 会创建一个内部虚拟网络,通常是 WSL 虚拟交换机。WSL2 实例会被分配一个私有子网 IP,例如 172.x.x.x 网段,再通过宿主机网络接口做 NAT 转换,从而访问外部网络。
核心特性#
- 网络可达性:
- WSL2 可以访问宿主机和外部网络;
- 宿主机可以通过 WSL2 的私有 IP 访问 WSL2;
- 局域网内其他设备通常无法直接访问 WSL2,需要额外配置端口转发或桥接。
- IP 动态性:WSL2 重启后可能分配新的私有 IP,稳定性较差。
- 端口转发:外部设备访问 WSL2 服务时,需要手动在 Windows 防火墙和虚拟交换机中配置端口转发规则,或借助自动转发工具。
- 性能:基础网络性能满足日常开发需求,但 NAT 转换会带来轻微开销。
适用场景#
- 本地开发(如运行数据库、后端服务,仅需宿主机访问)。
- 无需局域网内其他设备交互的场景。
Mirrored 模式:与宿主机共享网络#
工作原理#
Mirrored 是 Windows 11 22H2 及以上版本新增的模式,核心是将 WSL2 的网络接口与宿主机网络接口镜像对齐。
开启后,WSL2 会共享宿主机的网络配置,包括 Wi-Fi、以太网、VPN 等。它更像是和宿主机处于同一网络层面,因此拥有与宿主机相同的网络可达性。
核心特性#
- 网络可达性:WSL2 与宿主机共享网络环境,可以直接访问局域网内其他设备;外部设备也能通过宿主机 IP 直接访问 WSL2 服务,无需额外端口转发。
- 动态网络切换:宿主机从 Wi-Fi 切换到以太网时,WSL2 网络会同步更新。
- IP 分配:WSL2 不再单独分配私有 IP,而是复用宿主机的网络身份。
- 兼容性:对 VPN、企业网络策略的兼容性更好。部分复杂 VPN 环境下,NAT 模式可能失效,而 Mirrored 模式可以正常工作。
- 限制:仅支持 Windows 11 22H2 及以上版本。
适用场景#
- 需要局域网内其他设备访问 WSL2 服务,例如测试环境共享、多设备联调。
- 宿主机频繁切换网络(如笔记本电脑移动办公)。
- 需通过 VPN 访问企业内网的场景。
这次报错的原因#
切换到 Mirrored 模式后,WSL2 与 Windows 共享端口空间。Java 程序试图绑定的 26203 端口,已经被 Windows 宿主机中的其他进程占用,例如另一个 Java 程序或后台服务,于是触发端口冲突。
这也是为什么 NAT 模式下程序可以正常运行,而 Mirrored 模式下会报错。
解决方法#
1. 定位占用端口的进程#
在 Windows 中执行:
netstat -ano | findstr :26203
tasklist | findstr <PID>powershell在 WSL2 中执行:
sudo netstat -tulpn | grep 26203bash2. 释放冲突端口#
如果占用进程不是必要程序,可以直接在 Windows 任务管理器中按 PID 找到并结束它,或在 WSL2 中执行:
kill -9 <PID>bash3. 修改 Java 程序端口#
如果无法释放端口,就把 Java 程序的 JMX 端口改成未被占用的值,例如 26204:
java -Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=26204 \
-Dcom.sun.management.jmxremote.rmi.port=26204 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-jar your-program.jarbash总结#
NAT 和 Mirrored 没有绝对好坏,区别在于网络隔离程度。
NAT 更稳、更隔离,适合大多数本地开发;Mirrored 更接近宿主机网络,适合局域网访问、VPN 和代理场景,但也更容易遇到宿主机端口冲突。
这次问题的本质就是:为了解决代理镜像问题切到了 Mirrored 模式,同时引入了端口空间共享,最终暴露出 Windows 端已有进程占用 26203 的冲突。