RFC 6143 规范文档:The Remote Framebuffer Protocol
文章目录
- 1. 引言
- 2. 初始连接流程
- 2.1 TCP连接建立
- 2.2 协议版本协商
- 2.3 安全握手
- 3. 显示协议机制
- 3.1 核心概念
- 3.2 像素格式
- 4. 输入协议
- 4.1 键盘事件(KeyEvent)
- 4.2 鼠标事件(PointerEvent)
- 5. 协议消息详解
- 5.1 握手消息
- 5.2 初始化消息
- 5.3 客户端→服务器消息
- 5.4 服务器→客户端消息
- 6. 编码类型
- 6.1 标准编码
- 6.2 伪编码
- 6.3 Hextile编码处理流程
- 7. 协议工作流程
- 8. 安全性考虑
- 8.1 协议原生安全机制
- 8.2 推荐安全实践
- 9. IANA注册表
- 9.1 安全类型注册(部分)
- 9.2 消息类型范围
- 10. 实际应用与优化
- 10.1 性能优化策略
- 10.2 现代扩展实现
- 11. 协议演进历史
- 附录A:RFB协议状态机
- 附录B:协议消息结构图
- B.1 FramebufferUpdate 消息结构
- B.2 Hextile编码子矩形示例
- 附录C:协议数据流示例
- C.1 典型通信过程
- C.2 伪编码应用场景
1. 引言
Remote Framebuffer Protocol (RFB) 是一种轻量级、跨平台的远程图形访问协议,主要应用于虚拟网络计算(VNC)系统。其核心设计理念:
- 与图形系统解耦:不依赖特定GUI实现(如X11、Windows GDI)
- 客户端主导模型:由客户端主动请求屏幕更新
- 高效传输:支持多种编码方式和增量更新
- 强扩展性:通过编码类型协商适应不同场景
2. 初始连接流程
2.1 TCP连接建立
- 客户端连接服务器默认端口:5900(或5900+显示编号)
- 使用TCP协议进行可靠传输
2.2 协议版本协商
# 服务器发送协议版本
server_send(b"RFB 003.008\n") # 固定12字节# 客户端响应支持版本
client_send(b"RFB 003.008\n") # 取双方都支持的最高版本
2.3 安全握手
3. 显示协议机制
3.1 核心概念
- 帧缓冲区(Framebuffer):代表屏幕内容的二维像素数组
- 增量传输:仅传输变化的矩形区域
- 编码协商:客户端指定支持的编码列表
3.2 像素格式
struct PixelFormat {uint8 bits_per_pixel; // 像素深度(8/16/32)uint8 depth; // 颜色深度uint8 big_endian_flag; // 字节序(0=小端,1=大端)uint8 true_color_flag; // 是否真彩色(1=true)uint16 red_max; // 红色通道最大值uint16 green_max; // 绿色通道最大值uint16 blue_max; // 蓝色通道最大值uint8 red_shift; // 红色位偏移uint8 green_shift; // 绿色位偏移uint8 blue_shift; // 蓝色位偏移uint8 padding[3]; // 对齐填充
};
4. 输入协议
4.1 键盘事件(KeyEvent)
struct {uint8 message_type; // 消息类型 (固定为0x04)uint8 down_flag; // 按键状态 (1=按下, 0=释放)uint8 padding[2]; // 填充字节uint32 key; // 键值 (Keysym编码)
} KeyEvent;[消息类型:1][down:1][padding:2][key:4]
// down=1: 按键按下, down=0: 按键释放
// key: X11键码(兼容Windows/Mac)
4.2 鼠标事件(PointerEvent)
struct {uint8 message_type; // 消息类型 (固定为0x05)uint8 button_mask; // 按钮状态掩码uint16 x_position; // X坐标 (0到framebuffer宽度-1)uint16 y_position; // Y坐标 (0到framebuffer高度-1)
} PointerEvent;[消息类型:1][button-mask:1][x:16][y:16]
按钮掩码(button-mask):
位置 掩码值 (十六进制) 对应按钮
位0 0x01 左键
位1 0x02 中键/滚轮按下
位2 0x04 右键
位3 0x08 滚轮上滚 (扩展)
位4 0x10 滚轮下滚 (扩展)
位5 0x20 侧键后退 (扩展)
位6 0x40 侧键前进 (扩展)
5. 协议消息详解
5.1 握手消息
消息类型 | 方向 | 结构 |
---|---|---|
ProtocolVersion | 服务器→客户端 | “RFB XXX.YYY\n” (12字节) |
Security | 服务器→客户端 | [num-types:1][security-types] |
SecurityResult | 服务器→客户端 | [status:4][reason-string] |
5.2 初始化消息
消息类型 | 方向 | 结构 |
---|---|---|
ClientInit | 客户端→服务器 | [shared-flag:1] (1=共享连接) |
ServerInit | 服务器→客户端 | [width:16][height:16][pixel-format][name] |
5.3 客户端→服务器消息
类型ID | 消息名称 | 结构 | 功能说明 |
---|---|---|---|
0x00 | SetPixelFormat | [消息ID][padding:3][PixelFormat] | 设置像素格式 |
0x02 | SetEncodings | [消息ID][padding:1][num-enc:2][encodings] | 设置支持的编码类型 |
0x03 | FramebufferUpdateRequest | [消息ID][incremental:1][x][y][w][h] | 请求帧缓冲区更新 |
0x04 | KeyEvent | [消息ID][down][padding][key] | 发送键盘事件 |
0x05 | PointerEvent | [消息ID][button-mask][x][y] | 发送鼠标事件 |
0x06 | ClientCutText | [消息ID][padding:3][length:4][text] | 发送剪贴板文本 |
5.4 服务器→客户端消息
类型ID | 消息名称 | 结构 | 功能说明 |
---|---|---|---|
0x00 | FramebufferUpdate | [消息ID][padding:1][num-rect:2][rects] | 发送帧更新 |
0x01 | SetColorMapEntries | [消息ID][padding:1][first-color:2][colors] | 设置调色板 |
0x02 | Bell | [消息ID] | 触发客户端响铃 |
0x03 | ServerCutText | [消息ID][padding:3][length:4][text] | 发送服务器剪贴板文本 |
6. 编码类型
6.1 标准编码
编码ID | 名称 | 描述 |
---|---|---|
0 | Raw | 原始像素数据,无压缩 |
1 | CopyRect | 复制屏幕已有区域,仅传输源坐标 |
2 | RRE | 行程编码,适用于大面积纯色块 |
5 | Hextile | 分块处理(16x16),每块可选子编码 |
16 | ZRLE | Zlib压缩的行程编码,最高效的压缩方式 |
15 | TRLE | 透明行程编码,支持透明色 |
6.2 伪编码
编码ID | 名称 | 描述 |
---|---|---|
-239 | Cursor | 传输鼠标光标形状和热点位置 |
-223 | DesktopSize | 通知客户端桌面分辨率已改变 |
-258 | ExtendedClipboard | 扩展剪贴板支持(非标准) |
6.3 Hextile编码处理流程
7. 协议工作流程
8. 安全性考虑
8.1 协议原生安全机制
- VNC认证:使用DES加密挑战响应(已不安全)
- 无加密传输:像素数据和输入事件明文传输
8.2 推荐安全实践
-
SSH隧道加密
ssh -L 5901:localhost:5900 user@remote-server vncviewer localhost:5901
-
扩展安全类型
- TLS (安全类型 18)
- VeNCrypt (安全类型 19)
- SASL认证
-
网络层防护
- 防火墙限制访问IP
- VPN隧道保护
9. IANA注册表
RFB协议定义四类IANA注册表:
9.1 安全类型注册(部分)
值 | 名称 | 描述 |
---|---|---|
0 | Invalid | 无效类型 |
1 | None | 无认证 |
2 | VNC Authentication | VNC认证 |
5 | RA2 | RSA-AES加密 |
16 | Tight | TightVNC扩展 |
18 | TLS | TLS加密 |
19 | VeNCrypt | VeNCrypt安全层 |
9.2 消息类型范围
方向 | 范围 | 说明 |
---|---|---|
客户端→服务器 | 0-127 | RFC定义的核心消息 |
客户端→服务器 | 128-255 | 供应商特定扩展消息 |
服务器→客户端 | 0-127 | RFC定义的核心消息 |
服务器→客户端 | 128-255 | 供应商特定扩展消息 |
10. 实际应用与优化
10.1 性能优化策略
-
编码选择优先级:
ZRLE > Hextile > RRE > CopyRect > Raw
-
增量更新频率:
- 静态内容:降低请求频率
- 动态内容:增加请求频率
-
带宽自适应:
- 高带宽:高质量无损压缩
- 低带宽:降低颜色深度/分辨率
10.2 现代扩展实现
特性 | 实现方式 | 支持实现 |
---|---|---|
文件传输 | 自定义消息类型(0x80+) | TightVNC, UltraVNC |
多显示器支持 | Xinerama扩展 | TigerVNC, RealVNC |
视频流优化 | H.264编码扩展 | TurboVNC |
触摸屏支持 | 扩展PointerEvent | MobileVNC |
11. 协议演进历史
版本 | 发布时间 | 主要改进 |
---|---|---|
3.3 | 1998 | 初始公开版本 |
3.7 | 2003 | 安全类型列表协商 |
3.8 | 2011 | RFC 6143标准化,伪编码,IANA注册 |
3.9+ | 非标准 | 供应商扩展(文件传输、加密改进等) |
最新实现参考:
- TigerVNC
- LibVNC
- RealVNC
附录A:RFB协议状态机
附录B:协议消息结构图
B.1 FramebufferUpdate 消息结构
0 1 2 30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| msg-type | padding | num-rectangles |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rectangle 1 |
| (variable) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| rectangle ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
每个矩形区域结构:
0 1 2 30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| x-pos |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| y-pos |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| width |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| height |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| encoding-type | pixel-data |
| | (variable) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
B.2 Hextile编码子矩形示例
附录C:协议数据流示例
C.1 典型通信过程
Client: 连接TCP端口5900
Server: "RFB 003.008\n"
Client: "RFB 003.008\n"
Server: [0x01 0x02] (支持None和VNC认证)
Client: 选择0x02 (VNC认证)
Server: [16字节随机数]
Client: [DES加密的响应]
Server: [0x00000000] (认证成功)
Client: [0x01] (共享连接)
Server: [1280x720][PixelFormat]["My Desktop"]
Client: [SetPixelFormat][SetEncodings]
Client: [FramebufferUpdateRequest]
Server: [FramebufferUpdate (ZRLE编码)]
Client: [PointerEvent (移动鼠标)]
... (持续交互)