我安装了 Windows 11 和 WSL2(Ubuntu)。
我已经gdb
在 Windows 本地主机上设置了一个侦听器服务器,并想从 Wsl2 访问它,但似乎我的 Windows 机器和 WSL 正在使用不同的网络适配器。
>ipconfig
Windows IP Configuration
Ethernet adapter vEthernet (Default Switch):
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::1114:bb:d0ad:93f8%18
IPv4 Address. . . . . . . . . . . : 172.29.192.1
Subnet Mask . . . . . . . . . . . : 255.255.240.0
Default Gateway . . . . . . . . . :
Ethernet adapter vEthernet (WSL):
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : fe80::897:849a:5fed:1c6e%52
IPv4 Address. . . . . . . . . . . : 172.21.128.1
Subnet Mask . . . . . . . . . . . : 255.255.240.0
Default Gateway . . . . . . . . . :
我的服务器正在积极监听 8888 端口,可以在 Windows 上访问,但无法在 Ubuntu/WSL 上访问。
我已经从 Windows 防火墙和 Ubuntu 防火墙打开了 8888 端口
解决办法是什么?
答案1
localhost
不起作用,因为 WSL2 使用由 Windows 虚拟机平台(Hyper-V 的一个子集)创建的虚拟网络 (vNIC) 运行。在 WSL2 内部,localhost
是 vNIC 的地址。
WSL2 确实在 Windows 主机上设置了一个虚拟路由器,以允许连接到外部世界以及 Windows 主机。你可以通过以下方式看到这一点:
ip route
“默认通过”地址是用于 Windows 主机的地址。
您可以从上面或从 解析它/etc/resolv.conf
,但 WSL 还使用 Windows“计算机名称”设置了一个便捷的 mDNS(.local
域),它也用作hostname
WSL 实例的。
$(hostname)
通过连接来访问它.local
。
尝试:
ping "$(hostname).local"
或者,如果 ICMP 被阻止(在新的 Windows 11 安装中似乎如此),请使用 netcat。它在 WSL Ubuntu 安装中默认可用,但可能需要在其他发行版(如 openSUSE)中安装:
nc -zv "$(hostname).local" <portnumber>
参考: 从 WSL2 内部访问在 Windows 中运行的本地主机? NotTheDr01ds 的回答。
答案2
“Localhost” 始终指系统本身。当您运行主机操作系统和虚拟化操作系统时,您将运行 2 个系统,这两个系统都将其自身称为“localhost”。因此,您永远无法访问另一个系统的“localhost”,您需要使用它的外部 IP。
就你的情况而言,如果你想从 Ubuntu 系统访问主机 Windows 上运行的监听端口 8888 的服务,你必须访问172.29.192.1:8888
。只有实际提供服务的系统才必须监听端口并允许通过该端口进行新的传入连接。
因为 Ubuntu 是一个独立的系统,所以除非您安装了监听该端口的服务,否则不会有任何东西监听端口 8888。
答案3
进一步阐述@harrymc 和@NotTheDr01ds 的回答:
通常,您可以使用主机名从 wsl2 命令行联系 Windows 服务"$(hostname).local"
。如果此类连接似乎被阻止,您可以尝试以下操作:
检查 Windows 防火墙是否阻止了流量。一个简单的检查方法是将其关闭几秒钟,然后重复测试。如果有效,请添加适当的防火墙规则。
问题
nslookup "$(hostname).local"
。这将为您提供一组 IP。默认情况下,将使用第一个,但这可能不是有效的 IP。也尝试其他 IP。如果您找到一个有效的 IP,您可以为自己的系统定制一个简短的脚本,该脚本将始终返回正确的 IP。
答案4
从 WSL2 2.0.0 版本开始,有两个不错的选择(以及几个不太好的选择)。从我的Stack Overflow 上关于该主题的回答 1:
简短答案:
NAT(默认)WSL2 与 mDNS 联网
将你的 WSL2
hostname
(或编程/语言环境中的等效命令/功能)与".local"
(主机 mDNS 名称)连接起来应该 2让您获得访问权限。例如,在 Bash 中尝试:ping "$(hostname).local"
或者,假设你尝试从 Python 访问 MongoDB,如下所示这个问题:
import socket server = f'{socket.gethostname()}.local' host = f'mongodb://{socket.gethostname()}.local'
镜像模式 WSL2 网络
笔记:需要 Windows 11 23H2 或更高版本
在镜像模式下,
localhost
应该“正常工作”。要启用:将以下内容添加到您的
<windows_user_profile>/.wslconfig
:[wsl2] networkingMode=mirrored
退出 WSL 发行版
从 PowerShell运行
wsl --shutdown
然后重新启动 WSL
然后,您应该能够通过 访问在 Windows 中运行的服务
localhost
。请注意,在镜像模式下运行时,mDNS将不起作用。
更多解释:
选项 1:使用 mDNS 进行 NAT
WSL2 的默认网络模式是在虚拟 Hyper-V 交换机后面进行 NAT。直到最近,这还是仅有的WSL2 的网络模式。在此模式下,WSL2 使用由 Windows 虚拟机平台(Hyper-V 的一个子集)创建的虚拟网络 (vNIC) 运行。 里面WSL2,localhost
是 vNIC 的地址,而不是 Windows 主机的地址。
在此模式下,使用 Windows 主机的 mDNS 名称3通常是最简单的解决方案。
mDNS 已经成为 WSL2 的一项功能。将您的 WSL2 hostname
(或编程/语言环境中的等效命令/函数)与它连接".local"
起来即可获得访问权限。
如上所述,从 Bash 尝试:
ping "$(hostname).local"
例如,如果您的hostname
是“MyComputer”,那么 mDNS 应该是MyComputer.local
。
如果 ICMP 被阻止(在新的 Windows 11 安装中似乎如此),或者您想要测试与实际端口的连接,则使用netcat
而不是ping
。它在 WSL Ubuntu 安装中默认可用,但可能需要在其他发行版(如 openSUSE)中安装:
nc -zv "$(hostname).local" <portnumber>
另请参阅“其他 NAT/mDNS 注意事项”2。
选项 2:镜像网络模式
WSL2 2.0.0 版引入了新的镜像组网模式,可以简化很多网络接入问题。
在此模式下,Windows 网络接口将镜像到 WSL2。ip addr
例如,当您运行 时,您将看到(大部分)与ipconfig /all
从 PowerShell/CMD 运行时相同的接口。
因此,localhost
通过镜像路由视窗环回适配器。
脚注:
2重复(和新)信息
尽管我不愿意重复目前被接受的答案的一部分,但如上所述,目前被接受的答案首先是基于我的 Stack Overflow 版本。公平地说,@harrymc 确实在评论中询问我是否愿意在这里重新发布它,但我当时拒绝了。
不过,多年来,我已将新信息添加到 SO 版本中,但这些信息尚未转移到这个 SU 问题中。鉴于(现在)发生了巨大变化,我觉得这些信息也需要在这里。
SO版本是技术上离题了,目前已关闭。这个 SU 问题与主题相关,应该是发布有关该主题的新信息的规范问题。
2其他 NAT/mDNS 注意事项
mDNS 依赖于 Windows 主机来解析名称。如果您
/etc/resolv.conf
在 WSL 下更改了您的,那么这很可能不起作用。记得打开任何必要的防火墙端口。WSL2 被认为是独立网络与 Windows 主机的网络连接不同。Windows 会将 WSL2 的网络连接视为来自外部源。 (归功于@RamilGilfanov以获取指出这一点的评论)
首次从 WSL2 连接到特定端口时,Windows Defender(如果这是您的防火墙)通常会显示一个对话框,询问您是否要授予访问权限。但是,根据我的经验,这个对话框经常被埋没在下面由于鼠标点击、键盘等的时间,主窗口很容易被错过。
记住让您的 Windows 服务接受来自远程主机的连接。
许多服务器默认配置为绑定到
localhost
/127.0.0.1
。因为 WSL2 在 Windows 中看起来像偏僻的网络,您通常需要更新配置以绑定到0.0.0.0
特定地址。请注意,由于 WSL2 的地址在每次重新启动后都会发生变化,因此每次更新配置可能很困难。如果可能的话,
0.0.0.0
除非存在安全问题,否则请使用。由于 WSL 是为发展而不是生产,这不应该是个问题。
3从技术上讲,这是虚拟转变WSL2 用于与 Windows 和外界交互。
您可以通过以下方式查看:
ip route
这是您需要用于 Windows 主机的地址。
当然,您可以从路由中解析它(或者,如之前的答案中所述,从中解析/etc/resolv.conf
),但由于 WSL 设置了便捷的 mDNS(.local
域),因此使用它更容易。