X11(X Window System)是一种位图显示的视窗系统,X表示X协议,11是协议版本号。X 协议主要由 X server 和 X client 组成:
l X server 管理主机上与显示相关的硬件设置(如显卡、硬盘、鼠标等),它负责屏幕画面的绘制与显示,以及将输入设置(如键盘、鼠标)的动作告知 X client。
l X client (即 X 应用程序) 则主要负责事件的处理(即程序的逻辑)。
举个例子,如果用户点击了鼠标左键,因为鼠标归 X server 管理,于是 X server 就捕捉到了鼠标点击这个动作,然后它将这个动作告诉 X client,因为 X client 负责程序逻辑,于是 X client 就根据程序预先设定的逻辑(例如画一个圆),告诉 X server说:“请在鼠标点击的位置,画一个圆”。最后,X server 就响应 X client 的请求,在鼠标点击的位置,绘制并显示出一个圆。
由上可见,X Window系统的协议和架构 X基于客户端——服务器 模型。一个X服务器与多个客户端程序通讯。服务器接受对于图形输出(窗口)请求并反馈用户输入(键盘、鼠标、触摸屏)。服务器可能是一个能显示到其他显示系统的应用程序,也可能是控制某个PC的视频输出的系统程序,还可能是特殊硬件。
术语客户端-服务器——你的终端是"服务器",而应用程序是 “客户端”——这一概念经常困扰X的新用户,因为看起来似乎正好相反。但X采纳了应用程序而非最终用户或者硬件的视角:本地的X显示程序提供显示服务,所以它扮演了服务器;远端应用程序使用了该服务,所以它是客户端。
以下实践主要基于公司当前使用的Xvnc作为Xserver,xclock作为Xclient。
要实现的效果为在A机器的Xserver上绘制B机器的Xclient,因为Xserver选择的是Xvnc,所以可以通过novnc或者vncviewer访问Xserver来共享画面。
1.首先准备两台机器,A,B。在A上安装Xvnc,B上安装Xclock。使用Xshell分别访问A与B,当开启了Xshell的X11转发时,在B上直接输入Xclock命令可以在本地打开一个时钟。如下图:
但是我们的目标不是在本地打开时钟,所以需要关闭Xshell的X11转发功能(关键)。关闭转发后再次尝试xclock命令出现错误便可以了。
2.在A机器上开启Xserver,命令如下
Xvnc :1 -rfbport 4001 -SecurityTypes None -geometry 2560*936 -depth 16 &
命令中 “:1” 为指定要开启的display窗口序号为1;
“-rfbport 4001” 为指定vnc访问的端口为4001(此处端口通常为4000+窗口序号,防止端口占用冲突),后续使用novnc或vncviewer访问时需要用到;
"–SecurityTypes None"设置vnc认证类型为不认证。
“-geometry 2560*936” 设置Xserver的分辨率,到时候novnc访问时分辨率就是此时设置的值。
"-depth 16"设置位深度。
“&” 为后台运行。
3.在A机器上设置DISPLAY临时变量为之前指定的窗口序号
export DISPLAY=localhost:1.0
4.在A机器上设置Xserver 访问权限,允许B机器进行访问
xhost + {B.ip}
5.在A机器上设置防火墙(可以直接关闭防火墙),开启6001端口(要开启的端口号为6000+display窗口序号)
6.在B机器上设置DISPLAY参数
export DISPLAY={A.ip}:1.0
7.在B机器上启动xclient(此处为xclock)
xclock
8.使用novnc或者vncviewer进行验证,访问A机器的4001端口。
公司中的xfwd协议就是基于隧道转发方式进行实现,其本质就是利用ssh的隧道进行X11转发,将linux上的图像信息转发绘制到Xvnc上,后续再通过vncviewer进行访问,显示图像。
1.基本同基础实现中的步骤1,在此之外需要确认B机器的SSH Server配置文件/etc/ssh/sshd_config中,有以下配置
X11Forwarding yes
若没有需增加此配置,并重启sshd服务
2,3步同基础实现。
4.通过SSH命令访问B机器并启动xclock
ssh -X root@{B.ip} /bin/xclock
5.使用vncviewer或者novnc进行验证。
tmp目录下有.X1-lock目录,其下有各个文件 X0~Xn 标志着已经启动的Xserver。有时候启动Xserver会提示display已经被占用,但是又查不到对应进程时,就可以去/tmp目录下把对应的.Xn-lock文件删除后再启动即可。
在Linux/Unix类操作系统上, DISPLAY用来设置将图形显示到何处。格式为host:NumA.NumB ,host指Xserver所在的主机名或者ip地址.如果host为空, 则表示Xserver运行于本机, 并且图形程序(Xclient)使用unix socket方式连接到Xserver, 此时NumA和NumB表示连接的unix socket的路径, 如果NumA为0, 则表示连接到/tmp/.X11-unix/X0 .NumB则几乎总是0.
如果host为主机名或者IP地址,则图形程序使用TCP方式连接,此时,NumA为连接的端口减去6000的值, 例如:NumA为0, 则表示连接到6000端口;
当使用X11 forwording进行图像映射时,在client端(目标机器,即ssh连接的机器)会根据sshd_config中的配置X11DisplayOffset启动对应端口进行转发,配置默认值是10.即启动6010端口进行转发。有时候这会和Xserver启动的端口冲突,导致Xserver无法启动,这时就可以通过修改这个配置来避免冲突。