WSL2 图形界面
#wsl #x11
VcXsrv、X410 和 Xming 都是用于在 Windows 系统上运行 X11 应用程序的开源 X 服务器,主要作用是在 Windows 系统上为 X11 应用程序提供显示支持。但是考虑到近几年的Xming在维护方面较为落后,而且听说虽然X410需要付费但是可以一直试用,因此我们选择了X410作为我们的X服务器
首先我们需要了解一下,什么是X11,以及这些东西到底是做什么的。
X11 协议
X11 是一种网络透明的窗口系统协议,常用于 Unix/Linux 系统上。它允许图形用户界面的应用程序通过网络将其显示内容发送到 X 服务器。X 服务器负责显示窗口和处理用户输入(如鼠标点击、键盘输入等)。
在这种架构中,X 服务器负责屏幕输出和输入管理,X 客户端(应用程序)与 X 服务器通信来展示图形界面。而X 服务器是一个负责绘制图形和管理窗口的服务。在 Linux 系统上,X 服务器直接运行在本地,提供桌面显示。
当我们在 Windows 上运行 VcXsrv 或 Xming 时,它们就相当于一个虚拟的 X 服务器,模拟 Linux 系统的 X 服务器环境。Linux 应用程序通过 X11 协议将绘图请求发送给 VcXsrv/Xming,后者再把这些请求转化为 Windows 系统可以理解的图形指令,从而在 Windows 上显示。
在 WSL 中,X11 请求是通过 localhost
进行本地转发,因此性能非常高,并且通信延迟较低
WSLg (WSL GUI 支持)
WSL其实是有自己的图形化界面的解决方法的。自 WSL 2 之后,微软推出了原生支持 GUI 应用的 WSLg (Windows Subsystem for Linux GUI) 功能。它无需手动安装 VcXsrv 或 Xming,直接通过 WSL 提供对 Linux GUI 应用程序的原生支持。WSLg 在后台自动管理 X 服务器,使 Linux 应用程序的图形界面可以无缝显示在 Windows 上。
但是这个方法我觉得页面相对比较简陋,示例如下:
使用X服务器
我使用的是X410,因此下面的内容我将会用X410作为例子,并详细记录我探索的过程。
现在我们看到的页面就是这样了:
根据官方文档中的说法,我们只需要配置一个环境变量DISPLAY
,让wsl中的应用知道将图形请求发送到哪里就行了。
为了简单,我们直接编辑 .bashrc
文件,设置 DISPLAY
环境变量就行了。对于wsl1而言,我们这样做就足够了。
1 |
|
这将确保在每次启动 WSL 时,DISPLAY
变量都被正确设置。
但是我使用的是wsl2,这两个最大的区别就是,wsl的localhost和宿主机是同一个,而wsl2是不同的,因此也衍生出后面的mirror-mode网络模式,给我带来了一堆问题
根据官网的说法,我们需要这样做:
1 |
|
整个命令的作用就是从/etc/resolv.conf
这个文件中提取当前系统的 nameserver
IP 地址,并将它与 :0.0
结合,设置为 DISPLAY
变量。这种方法也许是有效的,但是我的情况有点复杂,并没有成功。
但是依旧出现了问题:
1 |
|
我们重新回去看刚才所执行的设置DISPLAY
变量的命令,这句命令中获取的主机server的ip是从resolv.conf
文件中提取出来的。我们看到,这个文件里面是长这个样子的:
1 |
|
但是我们使用ip route
的时候看到的内容是这样的:
1 |
|
也就是说,此时resolv.conf
显示的nameserver并不是指向主机的虚拟网络接口。因此无法显示是正常的。那么这个东西指向的是什么呢?
查了一下资料,resolv.conf
这个文件用于指定域名解析(DNS)服务器的地址。目前来看,他指向的是10.255.255.254
这个地址。我们返回去使用ip a
命令查看的时候,我们看到的是这样的:
1 |
|
我有开始怀疑,这个地址指向的是wls虚拟的 DNS 隧道,然后这个DNS隧道再将信息传递给主机系统的 DNS 服务。我们尝试将wsl2的dns隧道功能关闭之后,这个文件中的内容变成了这样:
1 |
|
这进一步证实了我刚才的想法。而我们在主机中通过ipconfig
命令查看:
1 |
|
我们看到,这个确实是WSL所虚拟出来的网络接口的地址。这种变化是因为我关闭了 WSL2 的 DNS 隧道管理。关闭隧道后,WSL2 不再自动生成 10.255.255.254
这样的虚拟 DNS,转而使用与 Windows 主机共享的虚拟网络适配器 (172.18.16.1
),通过此适配器进行网络通信和 DNS 查询。
因此为了规避这个问题,我们使用以下命令就能将图形请求发送到正确的接口上:
1 |
|
但是当我们同时使用mirrored网络模式和DNS隧道,然后还使用tun模式进行代理的的时候,以上两种方法获取到的主机接口都是错误的(属实是buff叠满了)。此时只能我们手动去配置。因此我的建议是使用nat网络模式,这样会使得一切都变得简单起来。