远程帧缓冲(RFB)协议
Tristan Richardson1 Kenneth R. Wood1刘茂华2译
(1. ORL Cambridge 2. 华北计算技术研究所)
1.引言
RFB(Remote Frame Buffer 远程帧缓冲)协议是一个用于远程访问图形用户界面的简单协议。由于RFB协议工作在帧缓冲层,因此它适用于所有的窗口系统和应用程序,如X11、Windows 3.1/95/NT和Macintosh等。
用户使用的远程终端(一般包括显示器、键盘和鼠标)称为RFB客户端,引起帧缓冲改变的终端(如窗口系统或应用程序)称为RFB服务器端。RFB协议工作流程如图所示。
协议包括RFB协议是一个真正的瘦客户端协议,RFB协议设计时主要考虑的是尽量减少对客户端的需求,在这种情况下,瘦客户端能够运行在大量广泛的硬件平台上,这样实现客户端的任务就尽可能的得到了简化。
遵守RFB协议的RFB客户端是一个无状态的客户端,若RFB客户端从一台RFB服务器断开后重新连接到RFB服务器端,RFB客户端的图形用户界面就已经被保存。另外,不同的RFB客户端终端能够连接到相同的RFB服务器终端上,在新的RFB客户端终端上能够得到和原来的RFB客户端终端相同的图形用户界面。从使用效果上看,用户应用程序的接口是完全动态的。只要存在适当的网络连接,用户就能够访问他们各自的应用程序,
并且在不同地方访问的应用程序的状态都能够得到保存。因此无论用户在哪里,都能够得到一个熟悉而统一的计算基础设施视图。
2.显示协议
RFB协议的显示部分主要基于一个简单的图形原理:将一个矩形像素数据绘制到一个给定的x和y坐标上。在显示器上绘制不同的用户接口组件看起来是非常低效的。但是不同的像素数据编码方式为权衡不同的物理参数如网络带宽、客户端绘制速度和服务器端处理速度提供了很大的灵活性。
这些矩形像素数据序列不断更新帧缓冲,帧缓冲更新是指从一个有效的帧缓冲状态到另一个有效的帧缓冲状态,因此在某种程度上和视频帧缓冲相似。帧缓冲更新矩阵一般是不重叠的,但是也存在重叠情况。
帧缓冲更新协议是依据RFB客户端的请求的不同而不同,即帧缓冲更新是在RFB客户端显式的请求更新帧缓冲时,RFB服务器将更新数据发送到RFB客户端,这就给协议提供了灵活性的质量控制。RFB客户端和网络速度越慢,帧缓冲的更新速度就越慢。对于一般的应用情况,帧缓冲在某个区域的变化很可能马上再次发生变化,对于慢速的RFB客户端和网络速度,帧缓冲的临时变化可以被忽略,从而减少了网络中的传输流量和RFB客户端的绘制开销。
3.输入协议
RFB协议的输入部分主要基于鼠标键盘标准工作站模型。在键盘被按下和鼠标被点击或移动后,输入事件被RFB客户端发送到RFB服务器端,这些输入事件还能够从其它非标准输入输出设备综合得到,如手写笔识别引擎能够产生键盘事件。
4.像素数据的表示
RFB客户端和RFB服务器端在开始交互过程中主要进行待传输数据的格式和编码方式的协商。协商过程在设计时主要考虑的是使RFB客户端的工作尽可能的简单。RFB服务器端应该向RFB客户端提供RFB客户端请求得到的数据。但是若RFB客户端能够对不同的数据格式和编码方式作相同的处理,RFB协议应该选择便于RFB服务器产生的数据格式和编码方式。
像素格式是指每一种颜通过像素值进行表示的方式。最常用的像素格式是24位和16位的真彩表示方式,像素值中的位域被直接转化为红、绿和蓝的强度,并且8位的颜映射表能够将一个任意的像素值直接转化为RGB强度值。
像素编码方式是指如何在网络上传输矩形像素数据,每一个矩形像素数据都包括一个前置头,前置头中包括了矩阵的x坐标和y坐标、矩阵的长和宽以及矩阵像素数据的编码方式,然后矩阵像素数据采用指定的编码方式进行编码。
能够通过增加新的编码方式对协议进行扩展。RFB协议当前定义的编码方式包括Raw 编码方式、Copy Rectangle编码方式、RRE(rise-and-run-length)编码方式、CoRRE(Compact RRE)编码方式和Hextile编码方式。在实际应用中一般采用Copy Rectangle编码方式和Hextile编码方式,由于两种编码方式对一般的桌面能够达到最好的压缩效果。还存在其它编码方式如用于有效传输静态图像的JPEG编码和用于有效传输动态图像的MPEG编码方式等。
4.1.Raw编码方式
最简单的编码方式是原始像素数据。在这种情况下,像素数据包括n个像素值,其中n是矩形长和宽的乘积。像素值以左上角为起点按扫描线的顺序从左到右的表示每一个像素。所有的RFB客户端必须能够处理原始编码方式的像素数据,并且如果RFB客户端没有特别指出需要某种编码方式的数据RFB服务器必须产生编码的像素数据。
4.2.Copy Rectangle编码方式
Copy Rectangle编码方式是一个简洁有效的编码方式,这种编码方式能够用于帧缓冲中的像素数据和客户端中的像素数据相同的情况。网络中传输的编码数据仅仅包括x坐标和y坐标。这个坐标位置指定了可以从帧缓冲中拷贝的像素数据,这能够用于大多数情况,如用户将一个窗口从一个坐标位置移到另一个坐标位置、用户拖动窗口滚动条等。另一个不太显著的应用是能够优化文本和重复模式的绘制。一个智
能的RFB服务器只会将一种模式发送一次并知道该模式之前在帧缓冲中的位置,然后采用Copy Rectangle编码方式发送该模式后来的显示方式。
4.3.RRE编码方式
RRE表示rise-and-run-length-encoding正如其名称所暗示的,它实际上是run-length编码方式的二维模拟。RRE编码方式不仅能够达到甚至超过run-length编码方式的压缩比率,而且以这种方式编码的数据在RFB客户端即使采用最简单的图形引擎也能够得到渲染。RRE编码方式设计的目标是达到一定的压缩比率并且使解压缩能力不够强大的RFB客户端也能够达到较好的交互效果。
RRE编码的基本思想是将矩形像素数据分割为子矩形区域,每个子矩形区域只包含一个像素值,所有子矩形区域的集合构成了原矩形区域的像素数据值。将一个给定的矩形按照近优化算法分割为子矩形区域也相对来说容易计算。
最后在网络上传输的编码数据是一个背景像素值vb(该值一般是整个矩形中最多的像素值)和一系列N个子矩形值,每个子矩形值都是一个五元组<v, x, y, w, h>,其中v(≠vb)是像素值,(x,y)是子矩形相对于原矩形左上角的坐标值,(w,h)是子矩形的宽度和高度。RFB客户端能够首先绘制一个利用背景像素值填充的原始矩形,然后绘制每个填充的子矩形的方式实现对原矩形的绘制。
4.4.CoRRE编码方式
CoRRE是一个RRE的变种,该编码方式保证传输的最大矩形不超过255×255个像素值。若RFB服务器发送的矩形大小超过了255×255个像素值,则RFB服务器应该对该矩形进行分割为若干个小矩形,然后将RFB小矩形发送到RFB客户端。对于这些RFB小矩形,只需要一个字节就能够对RFB小矩形的每一维进行表示。对于一般的桌面来说,CoRRE 编码方式能够达到比RRE更好的压缩比。实际上若对RFB矩形的大小限制的更加严格就能够达到最好的压缩比,当前实现CoRRE算法对矩形的要求是48×48。这主要是因为对那些编码效果不太好的矩形如包含图像数据的矩形都采用原始数据进行发送,对那些编码效果较好的一般采用CoRRE进行压缩。矩形大小越小,则矩形的控制粒度越精细。同采用RRE编码算法相比,RRE编码方式要么采用RRE编码方式发送整个原始矩形像素值,要么采用原始数据发送整个原始矩形像素值。但是由于每一个RFB小矩形都会产生一定的开销,因此将最大矩形的大小控制的太小将增加RFB小矩形的数量将使压缩比下降。
4.5.Hextile编码方式
Hextile编码方式是CoRRE编码方式的变种,矩形被分割为16×16大小的矩形片,从而使得子矩形的每一维的大小只需要4比特就能够进行表示,总共需要16比特。与CoRRE 编码方式不同,矩形片不是顶层的RFB子矩形。能够按照预定的方式将原始矩形分割为若干个矩形片。这表示每个矩形片的位置和大小不需要显示指定,每一个矩形片的编码内容按照预定的顺序一个接一个,矩形片的编码顺序是从左上角开始按照从左到右从上到下的顺序进行,若原始矩形的宽度不是16的倍数则最后一列矩形片的宽度将相应
的减小,若原始矩形的高度不是16的倍数则最后一行的矩形片的高度将相应的减小。
每一个矩形片的或者采用原始像素数据编码方式或者采用RRE的变种编码方式,编码方式可以通过每个矩形片的编码类型字节指定。每一个矩形片都有一个背景像素值。若某一个矩形片的背景像素值和前一个矩形片的背景像素值相同则不需要显示指定矩形片的背景像素值。若矩形片的所有子矩形都有相同的像素值,这能够通过指定整个矩形片的前景的方式指定。和背景相同,若某个矩形片的前景和前一个矩形片的前景相同则该矩形片的前景也不需要指定。
5.协议消息
RFB协议能够在所有可靠的传输层上运行如字节流或基于消息。协议包括两个阶段:握手阶段和正常交互阶段。
初始的握手阶段包括协议版本(ProtocolVersion)、认证(Authentication)、客户端初始化(ClientInitialisation)和服务器初始化(ServerInitialization)消息等,后面会描述。注意RFB客户端和RFB服务器端都会发送ProtocolVersion消息。
RFB协议在发送服务器初始化消息后进入到正常交互阶段。在这个阶段,客户端可以发送它所需要的任何消息,服务器将返回对应的结果。所有的消息以消息类型开始后面紧跟消息特定的数据。
后面协议消息的描述采用CARD8、CARD16、CARD32、INT8、INT16、INT32等基本数据类型进行描述,分别表示8位、16位和32位的无符号整数类型和8位、16位和32位的有符号整数类型。所有多字节整数类型(除像素数据值外)均采用大端(高位在前)顺序表示。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论