一、简介
RFB(远程帧缓冲)是一个用于远程访问图形用户接口的简单协议。由于它工作在帧缓冲层,所以适用于所有的桌面系统和应用,包括X11,Windows和Macintosh等。
我们把用户所在的一端(包括显示器、键盘和鼠标)被称为RFB客户端。而帧缓冲发生变化的一端(桌面系统和应用)称为RFB服务器。
(如下图)
RFB协议是一个瘦客户协议。协议设计的重点是减小对客户端的要求。这样,客户端可以运行在多种范围的硬件上,实现的任务是使客户端尽可能地简单。
RFB协议也使得客户端是“无状态”的。如果一个客户端和服务器断开了连接,稍后再一次连接到这台服务器上,用户的会话不会被关闭,状态会一直保持着。不同的客户端可以连接到同一个服务器上,在新的客户端上用户看到的是和原来的客户端上相同的图形用户接口。这样,用户的桌面变的完全可移动了。只要有合适的网络连接,用户就可以访问他个人的桌面应用,不论他走到哪里都可以连接到自己的会话上,而这些应用的状态可以一直保持着。
二、显示协议
RFB协议的显示部分基于一个简单的画图原理:“将一个矩形块的象素点放在给定位置(x,y)上”。这样做初看起来也许非常低效,因为要将用户所有的图形组件都画出来。但是由于可以为象素数据进行多种不同的编码,可以根据不同的参数比如网络带宽、客户端计算速度和服务器处理的速度等选择灵活的编码方式。
一系列的矩形块组成了一个帧缓冲更新。一个更新描述了帧缓冲从一个状态到另一个状态的变化情况,所以,某些方面,这和音频的帧很类似。每一个更新中的矩形块经常脱节(??不懂),但是这不必要。
更新协议是客户端“命令-驱动”型的。即服务器只有在收到客户端的请求才向其发送更新。这使得显示协议的质量可以调整。客户端和网络速度越慢,更新率就会越低。对于典型的应用,帧缓冲上相同区域的更新往往非常频繁。如果客户端或者网络非常慢,由于非常低的网络传输和客户端更新,帧缓冲上瞬时的状态都可以被忽略掉。
三、输入协议
输入协议是基于键盘和多键鼠标设备的标准工作站模型。当用户敲了一下键盘或者鼠标,或者移动了一下鼠标,客户端把这些输入事件简单地传送给服务器。输入事件可以由其它非标准I/O设备产生,如笔形手写板引擎也可以生成键盘事件。
四、象素数据的表示
RFB客户端和服务器最初的交互包括协商将要传输的象素数据的格式和编码类型。协商被设计成使客户端的工作尽可能的简单。底线是服务器必须可以一直提供客户端想要的象素数据的格式。但是如果客户端可以处理多种编码类型,它会选择对服务器来说最容易生成的编码。
象素格式是指象素值颜色表示法 最常用的象素格式是24位或16位真彩色,
编码是指怎样通过网络把矩形象素点的数据发送出去。每一个矩形象素点的数据被加了一个前缀包括它在屏幕上的位置,矩形象素点的宽度和高度,以及一个“编码类型”来描述该象素的编码方式。然后是经过编码的数据本身。
五、协议扩展
可以添加新的编码方式来扩展RFB协议。现在的编码方式有Raw,CopyRect,RRE,CoRRE,Hextile和ZRLE。实际上,常用的只有ZRLE,Hextile以及CopyRect编码,因为它们为典型的桌面提供了最好的压缩方法。
除了真实的编码,客户端可以使用“伪编码”来向服务器声明它支持一个特定的协议扩展。不支持扩展协议的服务器可以简单的忽略“伪编码”。注意,这意味着客户端必须事先假定服务器不支持协议的扩展,直到从服务器收到可以支持扩展的声明。
做到不同的编码和伪编码类型不相冲突很重要。一定要避免类似问题。RFB协议版本和编码类型由RealVNC公司维护。
六、消息协议
RFB协议可以在字节流或基于消息的可靠的传输上操作。RFB协议分两个阶段:初始握手阶段和协议交互阶段。
最初的握手阶段包括协议版本、安全类型、客户端初始化消息、服务器初始化消息等。注意客户端和服务器都发送一个协议版本消息。
在服务器初始化消息之后RFB协议执行正常的交互阶段。在这个阶段,客户端可以发送请求,然后从服务器接收到结果。所有的消息都开始于一个消息类型字节,后面跟着详细的消息数据。
下面关于协议消息的描述使用了U8、U16、U32、S8、S16和S32基本类型。分别表示8位、16位、32位无符号整型和8位、16位、32位有符号整型数据。多位的整型遵循big endian顺序。
PIXEL类型用来指一个象素值
6.1 初始的握手消息
6.1.1 协议版本
握手从服务器向客户端发送一个协议版本的消息开始。客户端获得服务器支持的RFB协议的最高版本号。然后客户端通过一个简单的消息来告诉服务器实际使用的协议版本号(可能和服务器发送的不一样。)客户端不能使用比服务器所能提供的还高的RFB协议版本。这种机制说明客户端和服务器都支持多个等级的向下兼容。
目前已经发布的协议版本有RFB3.3、3.7、3.8(RFB3.5有时会被客户端错误的报告,这样会被服务器解释成RFB3.3)。新编码或者伪编码类型一般对协议的版本没有要求,因为服务器能简单的忽略他不认识的编码。
6.1.2安全
协议版本确定之后,服务器和客户端必须协商此次连接的安全类型.
6.6伪编码
6.6.1 指针的伪编码
客户端要求伪编码是为了在客户端本地画鼠标指针,这样可以在网络连接慢 的情况下提高显示性能.
6.6.2 桌面的伪编码