前言
-
我们通常在进行远程配置板端的时候往往会出现一个问题,在不连接显示屏或者启用VNC服务的前提下(或者使用其他软件提供的功能),我们无法在远程终端看到板端的新窗口。
-
例如下图是一个通过远程SSH连接后企图在终端进行OpenCV窗口显示的代码报错
-
错误信息
“qt.qpa.xcb: could not connect to display”
表示 Qt 应用程序无法连接到显示服务器,通常是因为DISPLAY 环境变量
没有设置或者设置不正确。这个错误通常出现在尝试在没有图形界面的服务器上运行图形界面应用程序时,或者在远程X11 转发
没有正确配置的情况下。 -
本文介绍一种通过指定
-CX
或者-CY
的方式在Linux上通过Xorg
或者Wayland
进行SSH窗口转发的使用说明和配置方法,同时介绍几种测试的用法展示- RVIZ2窗口回传
- OpenCV窗口回传
- VScode窗口回传(不启用vscode-server)
-
需要注意双方必须支持
Xorg
或者Wayland
,因此Windows是行不通的!
1 SSH服务
1-1 介绍
SSH(Secure Shell)
是一种网络协议,用于计算机之间的加密登录和其他安全网络服务。它在非安全网络中为网络服务提供安全性,例如,通过在不安全的网络中创建安全通道来保护网络数据的传输。- 主要特点:
- 数据加密:SSH在客户端和服务器之间传输的数据都会进行加密处理,确保数据传输的安全性。
- 认证机制:SSH提供了多种认证方式,包括密码认证、基于密钥的认证等,增强了安全性。
- 数据完整性:SSH能够保证数据在传输过程中不被篡改。
- 远程登录:用户可以通过SSH登录到远程服务器,执行命令,进行系统管理。
- 端口转发:SSH支持
端口转发
,可以将本地的端口映射到远程服务器上的端口,或者将远程服务器的端口映射到本地。
- 使用场景:
- 远程登录:管理员可以通过SSH远程登录到服务器进行管理操作。
- 安全文件传输:配合
SFTP(SSH File Transfer Protocol)
或SCP(Secure Copy)
,可以实现安全的文件传输。 - 加密隧道:SSH可用于创建加密的隧道,保护数据流,例如,用于数据库的加密连接。
- X11转发:允许将X11应用程序的图形用户界面显示在本地机器上,即使应用程序实际上运行在远程服务器上。
- 网络设备管理:网络设备如路由器和交换机通常支持SSH,以便进行安全的远程管理。
1-2 Linux安装ssh
- 安装
sudo apt install openssh-server
- 启用ssh服务
sudo systemctl enable --now ssh
- 查询ssh状态
sudo systemctl status ssh
- 查询本地ip
ip addr
- 进行SSH连接的时候需要确保双方同时处于局域网下,然后通过用于名和远程主机的ip地址进行访问
ssh [用户名]@[客户端ip地址]
- 值得一提的是初次连接的时候可能会看到如下提示,这是向你确认客户端的SSH指纹。当我们第一次尝试连接到一个新的SSH服务器时,SSH客户端会显示服务器的公钥指纹,并询问我们是否信任这个服务器。这是为了防止中间人攻击。如果指纹匹配,输入
yes
继续连接。
The authenticity of host '192.168.1.100 (192.168.1.100)' can't be established.
ECDSA key fingerprint is SHA256:nThX/AQW5bp9z3PueB3Wur5M1P+RlCTQr9IbNP0L+yc.
Are you sure you want to continue connecting (yes/no)?
1-3 VScode插件vscode-server
配置SSH连接
-
vscode-server
是一个轻量级的服务器组件,它是 Visual Studio Code(VS Code)远程开发扩展的一部分。VS Code 是一个由微软开发的免费、开源的代码编辑器,它支持多种编程语言的语法高亮、智能代码完成、括号匹配、代码缩进、代码片段、代码对比差异、Git 控制等功能,并拥有一个功能丰富的扩展市场。 -
正常我们使用ssh进行远程连接的时候都会借助ssh的扩展服务
ssh-server
,在扩展商店中搜索Remote-SSH
可以进行插件下载 -
我们在
Remote-SSH
扩展中添加存在的SSH连接 -
输入密码
-
初次远程需要安装
vscode-server
-
下载后发现我们就可以远程连接到远程的版端
-
但是值得一说的是
vscode-server
在远端会持续运行,很耗费内存资源,即使在连接断开后也不会自动释放资源,在内存吃紧的板端需要注意(如果需要删除的话直接sudo rm -rf ~/.vscode-server
即可)
2 X11和Wayland
2-1 介绍
X11
和Wayland
是两种不同的显示服务器协议,它们在Linux和其他类Unix操作系统中用于图形用户界面的渲染和显示。X11
,也称为X Window System
,是Linux和其他类Unix操作系统中使用最广泛的显示服务器协议。它是由MIT在1987年开发的,目的是提供一个通用的图形用户界面框架。Wayland
是一个较新的显示服务器协议,旨在替代X11。它由Kristian Høgsberg在2008年开发,目标是提供一个更简单、更现代、更安全的显示服务器。
2-2 查询桌面系统使用的渲染协议
- 在终端输入下述bash指令可以查看自己电脑的协议,可能输出有-
x11
:表示当前会话正在使用X11显示服务器。
wayland
:表示当前会话正在使用Wayland显示服务器。mir
:表示当前会话正在使用Mir显示服务器tty
:通常意味着你当前不在图形用户界面(GUI)环境中,而是在一个基于文本的控制台会话中。(后面会说)
echo $XDG_SESSION_TYPE
- 以我的Ubuntu22.04LTS为例子,是以x11为协议
2-3 额外安装X11
和Wayland
- 如果终端中的
echo $XDG_SESSION_TYPE
命令输出为tty
,这通常意味着你当前不在图形用户界面(GUI)环境中,而是在一个基于文本的控制台会话中。在这种情况下,没有图形界面渲染协议在运行,因为你正在使用的是命令行界面。 - 这时候我们可以手动安装以下
X11
和Wayland
sudo apt update
sudo apt install wayland
sudo apt update
sudo apt install xorg
4 切换X11
和Wayland
- 如果想从
Wayland
切换到X11
,可以通过vim
编辑下述文件
sudo vim /etc/gdm3/custom.conf
- 找到这一行
WaylandEnable=false
- 修改即可
5 SSH使用-CX
或者-CY
进行窗口转发
- 在SSH中,
-C
选项用于启用压缩,可以减少数据传输量,加快传输速度。而-X
和-Y
选项用于启用X11转发,允许你从远程服务器运行图形界面程序,并在本地显示。
-CX
:这个组合选项启用了压缩和X11转发。使用-X
选项时,SSH会设置一个安全的X11转发,这意味着只有来自远程服务器的X11连接会被转发到本地机器。这通常是通过使用ssh-agent
来管理密钥,并设置DISPLAY
环境变量来实现的。-CY
:这个组合选项启用了压缩和较宽松的X11转发。与-X
不同,-Y
选项不会进行任何访问控制,这意味着任何应用程序都可以通过SSH连接使用你的X11显示。这可能会带来安全风险,因为它允许远程应用程序访问你的本地X11会话,包括可能截取你的键盘输入和其他屏幕活动。
- 如果GUI显示端使用的是
Xorg
ssh -CX [用户名]@[远端IP]
- 如果GUI显示端使用的是
Wayland
ssh -CY [用户名]@[远端IP]
3 使用示范
- 这里为本机电脑是
Xorg
3-1 rviz2
-
我们来尝试不制定
-CX
参数时候启用远程终端的rviz2服务 -
可以看到上述请求报错了,错误信息
“qt.qpa.xcb: could not connect to display”
表示 Qt 应用程序无法连接到显示服务器,通常是因为DISPLAY 环境变量
没有设置或者设置不正确。这个错误通常出现在尝试在没有图形界面的服务器上运行图形界面应用程序时,或者在远程X11 转发
没有正确配置的情况下。 -
那我们远程连接的时候制定参数
-CX
-
可以看到,我们的服务被正确启动了。
3-2 VScode(不启用vscode-server)
- 通过制定
-CX
参数启动VScode不会激活vs-server,也不会遗留残留内存占用。
3-3 OpenCV窗口连接
- 我们简单写一个opencv代码验证一下,如果没安装的朋友可以装一下
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
- 创建文件
touch video.py
- 把下属代码粘贴写入
cat > video.py<<EOF
import cv2
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
if ret:
cv2.imshow("frame", frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
- 不加参数直接运行报错
- 同样道理运行
-CX
参数
总结
- 本文分别介绍了SSH远程窗口转发
-CX
和-CY
的配置原理,讲解了X11
和Wayland
切换方法和三个例子进行SSH远程窗口转发-CX
的测试 - 如有错误,欢迎指出,感谢大家的支持!