基本概念
- VNC(Virtual Network Computing)是基于RFB(Remote Frame Buffer)协议进行通信,是一个基于平台无关的简单显示协议的超级瘦客户系统。
- VNC的缺省端口是main:5900(C/S)和http:5800(B/S)端口。
RFB协议基本概念
- RFB是一个远程图形用户的简单协议,是因为它工作在帧缓存级别上,所以它可以应用于所有的窗口系统。如:Windows、X11、Mac等。
- 远端用户使用机器的(如键盘、显示器、鼠标等),叫做RFB客户端 提供帧缓存变化的叫做RFB服务器。
- RFB是一个基于TCP的应用层协议(但是目前已经有很多支持UDP协议的VNC)。
- RFB是真正意义上的瘦客户机协议,其设计重点在于减少对客户端的硬件需求。这样就可以在不同硬件上实现客户端了。
- RFB对于客户端是无状态的。也就是说:如果客户端从服务器断开,那么当它重新连接该服务器时,客户端的状态会被保存。甚至,不同的客户端可以连接相同的服务器。而且新客户端可以获得前一个客户端的相同用户状态
RFB协议之显示协议
- 显示协议是建立在“把像素数据放在一个由x,y定位的方框内”这单一图形的基础上的。
- 通过矩形序列来完成帧缓存的更新。一次更新代表着从一个可用帧缓存状态转换到另一个可用。矩形的更新一般是分开的,但并不是必须分开。
- 显示协议的更新是由客户端驱动的,也就是说,更新只是在服务器响应客户端的请求时发生的。这样就使协议更新质量可变,客户端网络慢或者绘图慢时,更新也会变慢。
RFB协议之输入协议
- 输入协议是基于标准工作站的键盘和鼠标等设备的连接协议。
- 输入事件就是把客户端的输入发送到服务器。
- 这些输入事件也可以由非标准的I/O来综合或模拟。如:手写键盘可能产生一个键盘事件。
RFB协议之编码协议
像素数据的显示
- 编码原则:服务器必须按照客户端要求的格式来提供像素数据。如果客户端可以处理多种数据格式,则一般选择服务器易于生成的格式
- 像素格式设计如何通过像素值来表示不同的颜色。最常用的一般是24位或16位的“真彩色”,它通过位来实现像素值到RGB的转换。8位“颜色映射”可以实现任意像素值到RGB亮度的转换。
- 编码指一个矩形的像素数据如何通过网络传输。每个像素数据的矩形都加了一个头,给定矩形在屏幕上的X、Y坐标,以及矩形的宽和高。同时指定编码类型。
- 数据本身遵循特定的编码,目前的编码方式有:Raw、CopyRect、RRE、Hextile和ZRLE。实际一般采用ZRLE、Hextile和CopyRect。此外还有用于静态图片格式的JPEG和用于动态图片的MPEG。
- 协议可以通过增加新的编码方式进行扩展
RFB协议之协议扩展
- 协议一般可以通过三种方式扩展:新的编码方式、伪编码方式和新的安全方式
- 扩展协议必须由客户端和服务器同时兼容才会生效
RFB协议之协议消息
- RFB协议可以进行可靠的传输,如字节流或基于消息的。
- RFB协议是基于TCP/IP协议簇的。
- RFB协议由三步连接。首先是握手报文,目的是对协议版本和加密方式进行协商。第二步是初始化报文,主要用于客户和服务器的初始化消息。最后就是正常的协议交互。
- 所有的消息以消息类型开始,接下来是消息数据
- 协议消息描述的基本类型有:U8、U16、U32、S8、S16、S32。(U-无符号,S-有符号)
- 所有整数字节(除像素值外)遵循big endian顺序。
RFB协议之协议流程
其中:
- 客户端初始化消息为一个字节的消息,用来表示是否允许服务器其他客户继续连接,即共享标志。
- 服务器初始化消息则是告知客户端帧缓存的高、宽、像素格式和桌面相关名称等。
RFB协议之协议流程(像素格式)
- 用设置象素格式消息来请求另一种象素格式。bits-per-pixel是表示每个像素值需要的位数。这个数字必须大于等于depth,而depth用来表示像素值中有用的位数。
- 要在0—红色最大值之间找一个红色值,按照以下步骤进行:
1、遵循big-endian 标志进行象素值。(例如:如果big-endian 标志为0,主机的字节顺序是big endian,然后交换)。
2、使用红色—替换将右边替换。
3、和红色最大值进行逻辑与(按照主机字节顺序)。 - 如果真彩标志是零,那么服务器使用的象素值不是直接由红、绿、蓝的亮度组成,但是服务为索引到颜色图中去。
RFB协议之协议流程(客户端消息)
- 所有客户端到服务器的消息第一个字节都是消息类型,数据类型为U8。
RFB协议之协议流程(服务器消息)
- 帧缓存更新 设置颜色映射 响铃事件 服务器剪切板
RFB协议之编码格式
RFB协议之编码格式(Raw)
- 原始编码即采用原始的像素数据,而不进行任何加工处理。这种编码方式最简单,但是效率也最低。
- RFB要求所有的客户都必须能够处理这种编码格式,并且当客户没有指明编码方式时,默认采用Raw格式
RFB协议之编码格式(CopyRect)
- 复制矩形编码对于客户端已经有了相同的像素数据时非常简单和有效。这种编码方式在网络中表现为x,y坐标,让客户端去拷贝那个矩形的像素数据。
- 复制矩形编码是对于像素值完全相同的一组矩形,只发送第一个矩形的全部数据,随后的矩形只发送左上角的x,y坐标。实际上复制矩形编码主要指随后的一系列x,y坐标,而对于第一个矩形采用何种编码方式没有限制。
RFB协议之编码格式(RRE)
- 二维行程编码(rise-and-run-length),表示提升和运行长度。是把像素矩形的数据分成一些子区域,和一些压缩原始区域的单元。
RFB协议之编码格式(CoRRE)
- CoRRE是RRE的变体,它把发送的最大矩形限制在255*255个像素以内,用一个字节就能表示像素的维度。如果服务器想发送一个更大的矩形,就把这个矩形划分成几个更小的矩形即可。
- 矩形的大小越小,就越能得到更好的压缩度。但是矩形数量太多也会造成开销大,所以目前一般采用48*48的最大值。
RFB协议之编码格式(Hextile)
- Hextile是RRE的变体,矩形被分割成16*16的小片,允许每个小片的位数为4位,总共16位。
- 矩形被分割的小片是自左到右、自上到下的顺序,如果不足16,则按真实大小分割。
- 每个小片可以用Raw编码,也可以用RRE编码的变种。每个小片有个背景值,可以与前一个小片取相同值,这样就可以不明确定义。如果小片的子矩形有相同的像素值,也可以通过前一个小片获得。
RFB协议之编码格式(ZRLE编码)
- ZRLE(Zlib Run-length Encoding),它结合了zlib压缩、片技术、调色板和运行长度编码。
- 在传输中,矩形以4字节长度区域开始,紧接着是zlib压缩的数据,一个单一的zlib“流”对象被用在RFB协议连接上,所以ZRLE矩形必须严格的按顺序编码和译码。