Internet Engineering Task Force (IETF)                     T. Richardson
Request for Comments: 6143                                     J. Levine
Category: Informational                                     RealVNC Ltd.
ISSN: 2070-1721                                               March 2011
        
Internet Engineering Task Force (IETF)                     T. Richardson
Request for Comments: 6143                                     J. Levine
Category: Informational                                     RealVNC Ltd.
ISSN: 2070-1721                                               March 2011
        

The Remote Framebuffer Protocol

远程帧缓冲协议

Abstract

摘要

RFB ("remote framebuffer") is a simple protocol for remote access to graphical user interfaces that allows a client to view and control a window system on another computer. Because it works at the framebuffer level, RFB is applicable to all windowing systems and applications. This document describes the protocol used to communicate between an RFB client and RFB server. RFB is the protocol used in VNC.

RFB(“远程帧缓冲区”)是一个简单的协议,用于远程访问图形用户界面,允许客户端查看和控制另一台计算机上的窗口系统。因为它在帧缓冲区级别工作,所以RFB适用于所有窗口系统和应用程序。本文档描述用于RFB客户端和RFB服务器之间通信的协议。RFB是VNC中使用的协议。

Status of This Memo

关于下段备忘

This document is not an Internet Standards Track specification; it is published for informational purposes.

本文件不是互联网标准跟踪规范;它是为了提供信息而发布的。

This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Not all documents approved by the IESG are a candidate for any level of Internet Standard; see Section 2 of RFC 5741.

本文件是互联网工程任务组(IETF)的产品。它代表了IETF社区的共识。它已经接受了公众审查,并已被互联网工程指导小组(IESG)批准出版。并非IESG批准的所有文件都适用于任何级别的互联网标准;见RFC 5741第2节。

Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc6143.

有关本文件当前状态、任何勘误表以及如何提供反馈的信息,请访问http://www.rfc-editor.org/info/rfc6143.

Copyright Notice

版权公告

Copyright (c) 2011 IETF Trust and the persons identified as the document authors. All rights reserved.

版权所有(c)2011 IETF信托基金和确定为文件作者的人员。版权所有。

This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.

本文件受BCP 78和IETF信托有关IETF文件的法律规定的约束(http://trustee.ietf.org/license-info)自本文件出版之日起生效。请仔细阅读这些文件,因为它们描述了您对本文件的权利和限制。从本文件中提取的代码组件必须包括信托法律条款第4.e节中所述的简化BSD许可证文本,并提供简化BSD许可证中所述的无担保。

Table of Contents

目录

   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
   2.  Initial Connection . . . . . . . . . . . . . . . . . . . . . .  4
   3.  Display Protocol . . . . . . . . . . . . . . . . . . . . . . .  4
   4.  Input Protocol . . . . . . . . . . . . . . . . . . . . . . . .  5
   5.  Representation of Pixel Data . . . . . . . . . . . . . . . . .  5
   6.  Protocol Versions and Extensions . . . . . . . . . . . . . . .  6
   7.  Protocol Messages  . . . . . . . . . . . . . . . . . . . . . .  7
     7.1.  Handshake Messages . . . . . . . . . . . . . . . . . . . .  8
       7.1.1.  ProtocolVersion Handshake  . . . . . . . . . . . . . .  8
       7.1.2.  Security Handshake . . . . . . . . . . . . . . . . . .  8
       7.1.3.  SecurityResult Handshake . . . . . . . . . . . . . . . 10
     7.2.  Security Types . . . . . . . . . . . . . . . . . . . . . . 10
       7.2.1.  None . . . . . . . . . . . . . . . . . . . . . . . . . 10
       7.2.2.  VNC Authentication . . . . . . . . . . . . . . . . . . 10
     7.3.  Initialization Messages  . . . . . . . . . . . . . . . . . 11
       7.3.1.  ClientInit . . . . . . . . . . . . . . . . . . . . . . 11
       7.3.2.  ServerInit . . . . . . . . . . . . . . . . . . . . . . 11
     7.4.  Pixel Format Data Structure  . . . . . . . . . . . . . . . 12
     7.5.  Client-to-Server Messages  . . . . . . . . . . . . . . . . 13
       7.5.1.  SetPixelFormat . . . . . . . . . . . . . . . . . . . . 13
       7.5.2.  SetEncodings . . . . . . . . . . . . . . . . . . . . . 14
       7.5.3.  FramebufferUpdateRequest . . . . . . . . . . . . . . . 15
       7.5.4.  KeyEvent . . . . . . . . . . . . . . . . . . . . . . . 16
       7.5.5.  PointerEvent . . . . . . . . . . . . . . . . . . . . . 19
       7.5.6.  ClientCutText  . . . . . . . . . . . . . . . . . . . . 19
     7.6.  Server-to-Client Messages  . . . . . . . . . . . . . . . . 20
       7.6.1.  FramebufferUpdate  . . . . . . . . . . . . . . . . . . 20
       7.6.2.  SetColorMapEntries . . . . . . . . . . . . . . . . . . 21
       7.6.3.  Bell . . . . . . . . . . . . . . . . . . . . . . . . . 22
       7.6.4.  ServerCutText  . . . . . . . . . . . . . . . . . . . . 22
     7.7.  Encodings  . . . . . . . . . . . . . . . . . . . . . . . . 22
       7.7.1.  Raw Encoding . . . . . . . . . . . . . . . . . . . . . 23
       7.7.2.  CopyRect Encoding  . . . . . . . . . . . . . . . . . . 23
       7.7.3.  RRE Encoding . . . . . . . . . . . . . . . . . . . . . 23
       7.7.4.  Hextile Encoding . . . . . . . . . . . . . . . . . . . 24
       7.7.5.  TRLE . . . . . . . . . . . . . . . . . . . . . . . . . 27
       7.7.6.  ZRLE . . . . . . . . . . . . . . . . . . . . . . . . . 30
     7.8.  Pseudo-Encodings . . . . . . . . . . . . . . . . . . . . . 30
       7.8.1.  Cursor Pseudo-Encoding . . . . . . . . . . . . . . . . 30
       7.8.2.  DesktopSize Pseudo-Encoding  . . . . . . . . . . . . . 31
   8.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 31
     8.1.  RFB Security Types . . . . . . . . . . . . . . . . . . . . 32
       8.1.1.  Registry Name  . . . . . . . . . . . . . . . . . . . . 32
       8.1.2.  Registry Contents  . . . . . . . . . . . . . . . . . . 32
     8.2.  Client-to-Server Message Types . . . . . . . . . . . . . . 32
       8.2.1.  Registry Name  . . . . . . . . . . . . . . . . . . . . 32
        
   1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  3
   2.  Initial Connection . . . . . . . . . . . . . . . . . . . . . .  4
   3.  Display Protocol . . . . . . . . . . . . . . . . . . . . . . .  4
   4.  Input Protocol . . . . . . . . . . . . . . . . . . . . . . . .  5
   5.  Representation of Pixel Data . . . . . . . . . . . . . . . . .  5
   6.  Protocol Versions and Extensions . . . . . . . . . . . . . . .  6
   7.  Protocol Messages  . . . . . . . . . . . . . . . . . . . . . .  7
     7.1.  Handshake Messages . . . . . . . . . . . . . . . . . . . .  8
       7.1.1.  ProtocolVersion Handshake  . . . . . . . . . . . . . .  8
       7.1.2.  Security Handshake . . . . . . . . . . . . . . . . . .  8
       7.1.3.  SecurityResult Handshake . . . . . . . . . . . . . . . 10
     7.2.  Security Types . . . . . . . . . . . . . . . . . . . . . . 10
       7.2.1.  None . . . . . . . . . . . . . . . . . . . . . . . . . 10
       7.2.2.  VNC Authentication . . . . . . . . . . . . . . . . . . 10
     7.3.  Initialization Messages  . . . . . . . . . . . . . . . . . 11
       7.3.1.  ClientInit . . . . . . . . . . . . . . . . . . . . . . 11
       7.3.2.  ServerInit . . . . . . . . . . . . . . . . . . . . . . 11
     7.4.  Pixel Format Data Structure  . . . . . . . . . . . . . . . 12
     7.5.  Client-to-Server Messages  . . . . . . . . . . . . . . . . 13
       7.5.1.  SetPixelFormat . . . . . . . . . . . . . . . . . . . . 13
       7.5.2.  SetEncodings . . . . . . . . . . . . . . . . . . . . . 14
       7.5.3.  FramebufferUpdateRequest . . . . . . . . . . . . . . . 15
       7.5.4.  KeyEvent . . . . . . . . . . . . . . . . . . . . . . . 16
       7.5.5.  PointerEvent . . . . . . . . . . . . . . . . . . . . . 19
       7.5.6.  ClientCutText  . . . . . . . . . . . . . . . . . . . . 19
     7.6.  Server-to-Client Messages  . . . . . . . . . . . . . . . . 20
       7.6.1.  FramebufferUpdate  . . . . . . . . . . . . . . . . . . 20
       7.6.2.  SetColorMapEntries . . . . . . . . . . . . . . . . . . 21
       7.6.3.  Bell . . . . . . . . . . . . . . . . . . . . . . . . . 22
       7.6.4.  ServerCutText  . . . . . . . . . . . . . . . . . . . . 22
     7.7.  Encodings  . . . . . . . . . . . . . . . . . . . . . . . . 22
       7.7.1.  Raw Encoding . . . . . . . . . . . . . . . . . . . . . 23
       7.7.2.  CopyRect Encoding  . . . . . . . . . . . . . . . . . . 23
       7.7.3.  RRE Encoding . . . . . . . . . . . . . . . . . . . . . 23
       7.7.4.  Hextile Encoding . . . . . . . . . . . . . . . . . . . 24
       7.7.5.  TRLE . . . . . . . . . . . . . . . . . . . . . . . . . 27
       7.7.6.  ZRLE . . . . . . . . . . . . . . . . . . . . . . . . . 30
     7.8.  Pseudo-Encodings . . . . . . . . . . . . . . . . . . . . . 30
       7.8.1.  Cursor Pseudo-Encoding . . . . . . . . . . . . . . . . 30
       7.8.2.  DesktopSize Pseudo-Encoding  . . . . . . . . . . . . . 31
   8.  IANA Considerations  . . . . . . . . . . . . . . . . . . . . . 31
     8.1.  RFB Security Types . . . . . . . . . . . . . . . . . . . . 32
       8.1.1.  Registry Name  . . . . . . . . . . . . . . . . . . . . 32
       8.1.2.  Registry Contents  . . . . . . . . . . . . . . . . . . 32
     8.2.  Client-to-Server Message Types . . . . . . . . . . . . . . 32
       8.2.1.  Registry Name  . . . . . . . . . . . . . . . . . . . . 32
        
       8.2.2.  Registry Contents  . . . . . . . . . . . . . . . . . . 32
     8.3.  Server-to-Client Message Types . . . . . . . . . . . . . . 33
       8.3.1.  Registry Name  . . . . . . . . . . . . . . . . . . . . 33
       8.3.2.  Registry Contents  . . . . . . . . . . . . . . . . . . 33
     8.4.  RFB Encoding Types . . . . . . . . . . . . . . . . . . . . 34
       8.4.1.  Registry Name  . . . . . . . . . . . . . . . . . . . . 34
       8.4.2.  Registry Contents  . . . . . . . . . . . . . . . . . . 34
   9.  Security . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
   10. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 36
   11. References . . . . . . . . . . . . . . . . . . . . . . . . . . 36
     11.1. Normative References . . . . . . . . . . . . . . . . . . . 36
     11.2. Informative References . . . . . . . . . . . . . . . . . . 36
   Appendix A.  Differences in Earlier Protocol Versions  . . . . . . 38
     A.1.  Differences in the Version 3.3 Protocol  . . . . . . . . . 38
     A.2.  Differences in the Version 3.7 Protocol  . . . . . . . . . 38
        
       8.2.2.  Registry Contents  . . . . . . . . . . . . . . . . . . 32
     8.3.  Server-to-Client Message Types . . . . . . . . . . . . . . 33
       8.3.1.  Registry Name  . . . . . . . . . . . . . . . . . . . . 33
       8.3.2.  Registry Contents  . . . . . . . . . . . . . . . . . . 33
     8.4.  RFB Encoding Types . . . . . . . . . . . . . . . . . . . . 34
       8.4.1.  Registry Name  . . . . . . . . . . . . . . . . . . . . 34
       8.4.2.  Registry Contents  . . . . . . . . . . . . . . . . . . 34
   9.  Security . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
   10. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 36
   11. References . . . . . . . . . . . . . . . . . . . . . . . . . . 36
     11.1. Normative References . . . . . . . . . . . . . . . . . . . 36
     11.2. Informative References . . . . . . . . . . . . . . . . . . 36
   Appendix A.  Differences in Earlier Protocol Versions  . . . . . . 38
     A.1.  Differences in the Version 3.3 Protocol  . . . . . . . . . 38
     A.2.  Differences in the Version 3.7 Protocol  . . . . . . . . . 38
        
1. Introduction
1. 介绍

RFB ("remote framebuffer") is a simple protocol for remote access to graphical user interfaces. Because it works at the framebuffer level, it is applicable to all windowing systems and applications, including X11, Windows, and Macintosh. RFB is the protocol used in VNC. The protocol is widely implemented and has had fairly good interoperability.

RFB(“远程帧缓冲区”)是一种用于远程访问图形用户界面的简单协议。因为它在帧缓冲区级别工作,所以它适用于所有窗口系统和应用程序,包括X11、Windows和Macintosh。RFB是VNC中使用的协议。该协议得到了广泛的应用,具有良好的互操作性。

The remote endpoint where the user sits (typically with a display, keyboard, and pointer) is called the RFB client or viewer. The endpoint where changes to the framebuffer originate (i.e., the windowing system and applications) is known as the RFB server.

用户所在的远程端点(通常带有显示器、键盘和指针)称为RFB客户端或查看器。对帧缓冲区进行更改的端点(即窗口系统和应用程序)称为RFB服务器。

RFB is a "thin client" protocol. The emphasis in the design of the RFB protocol is to make very few requirements of the client. In this way, clients can run on the widest range of hardware, and the task of implementing a client is made as simple as possible.

RFB是一种“瘦客户机”协议。RFB协议设计的重点是对客户机的要求很少。通过这种方式,客户机可以在最广泛的硬件上运行,实现客户机的任务变得尽可能简单。

The protocol also makes the client stateless. If a client disconnects from a given server and subsequently reconnects to that same server, the state of the user interface is preserved. Furthermore, a different client endpoint can be used to connect to the same RFB server. At the new endpoint, the user will see exactly the same graphical user interface as at the original endpoint. In effect, the interface to the user's applications becomes completely mobile. Wherever suitable network connectivity exists, the user can access their own personal applications, and the state of these applications is preserved between accesses from different locations. This provides the user with a familiar, uniform view of the computing infrastructure wherever they go.

该协议还使客户端无状态。如果客户端断开与给定服务器的连接,然后重新连接到同一服务器,则用户界面的状态将保留。此外,可以使用不同的客户端端点连接到同一RFB服务器。在新端点,用户将看到与原始端点完全相同的图形用户界面。实际上,用户应用程序的界面变得完全可移动。只要存在合适的网络连接,用户就可以访问自己的个人应用程序,并且这些应用程序的状态在不同位置的访问之间保持不变。这为用户提供了一个熟悉的、统一的计算基础设施视图,无论他们走到哪里。

The RFB protocol has evolved over the past decade, and has been implemented several times, including at least one open source version. This document describes the RFB protocol as actually implemented, so that future implementers can interoperate with existing clients and servers.

RFB协议在过去十年中不断发展,已经实现了好几次,包括至少一个开源版本。本文档描述了实际实现的RFB协议,以便未来的实现者能够与现有的客户机和服务器进行互操作。

2. Initial Connection
2. 初始连接

An RFB server is typically a long-lived process that maintains the state of a framebuffer. RFB clients typically connect, communicate with the server for a period of time to use and manipulate the framebuffer, then disconnect. A subsequent RFB session will then pick up where a prior session left off, with the state of the framebuffer intact.

RFB服务器通常是维持帧缓冲区状态的长期进程。RFB客户端通常与服务器连接、通信一段时间以使用和操作帧缓冲区,然后断开连接。随后的RFB会话将在前一个会话停止的位置拾取,帧缓冲区的状态保持不变。

An RFB client contacts the server on TCP port 5900. On systems with multiple RFB servers, server N typically listens on port 5900+N, analogous to the way that X Window servers listen on port 6000+N.

RFB客户端通过TCP端口5900与服务器联系。在具有多个RFB服务器的系统上,服务器N通常侦听端口5900+N,类似于X Window服务器侦听端口6000+N的方式。

Some browser-based clients use a Java application to run the RFB protocol. RFB servers sometimes provide a simple HTTP server on port 5800 that provides the requisite Java applet.

一些基于浏览器的客户端使用Java应用程序来运行RFB协议。RFB服务器有时在端口5800上提供一个简单的HTTP服务器,该服务器提供必要的Java小程序。

In some cases, the initial roles of the client and server are reversed, with the RFB client listening on port 5500, and the RFB server contacting the RFB client. Once the connection is established, the two sides take their normal roles, with the RFB server sending the first handshake message.

在某些情况下,客户端和服务器的初始角色是相反的,RFB客户端监听端口5500,RFB服务器联系RFB客户端。一旦建立了连接,双方将扮演正常角色,RFB服务器将发送第一条握手消息。

Note that the only port number assigned by IANA for RFB is port 5900, so RFB clients and servers should avoid using other port numbers unless they are communicating with servers or clients known to use the non-standard ports.

请注意,IANA为RFB分配的唯一端口号是端口5900,因此RFB客户端和服务器应避免使用其他端口号,除非它们与已知使用非标准端口的服务器或客户端通信。

3. Display Protocol
3. 显示协议

The display side of the protocol is based around a single graphics primitive: "put a rectangle of pixel data at a given x,y position". This might seem an inefficient way of drawing many user interface components. However, allowing various different encodings for the pixel data gives us a large degree of flexibility in how to trade off various parameters such as network bandwidth, client drawing speed, and server processing speed.

协议的显示端基于一个图形原语:“在给定的x,y位置放置一个像素数据矩形”。这似乎是一种绘制许多用户界面组件的低效方法。然而,允许对像素数据进行各种不同的编码使我们在如何权衡各种参数(如网络带宽、客户端绘制速度和服务器处理速度)方面具有很大的灵活性。

A sequence of these rectangles makes a framebuffer update (simply referred to here as "update"). An update represents a change from one valid framebuffer state to another, so in some ways is similar to a frame of video. The rectangles in an update are usually but not always disjoint.

这些矩形的序列进行帧缓冲区更新(这里简称为“更新”)。更新表示从一个有效帧缓冲区状态到另一个有效帧缓冲区状态的更改,因此在某些方面类似于视频帧。更新中的矩形通常是不相交的,但并不总是不相交的。

The update protocol is demand-driven by the client. That is, an update is only sent from the server to the client in response to an explicit request from the client. This gives the protocol an adaptive quality. The slower the client and the network are, the lower the rate of updates. With typical applications, changes to the same area of the framebuffer tend to happen soon after one another. With a slow client or network, transient states of the framebuffer can be ignored, resulting in less network traffic and less drawing for the client.

更新协议由客户机按需驱动。也就是说,更新只从服务器发送到客户端,以响应客户端的显式请求。这使协议具有自适应质量。客户端和网络速度越慢,更新速率越低。对于典型的应用程序,对帧缓冲区的相同区域的更改往往是一个接一个地发生。对于较慢的客户端或网络,可以忽略帧缓冲区的瞬态状态,从而减少网络流量和客户端的绘图。

After the initial handshake sequence, the protocol is asynchronous, with each side sending messages as needed. The server must not send unsolicited updates. An update must only be sent in response to a request from the client. When several requests from the client are outstanding, a single update from the server may satisfy all of them.

在初始握手序列之后,协议是异步的,每一方根据需要发送消息。服务器不得发送未经请求的更新。必须仅在响应客户端的请求时发送更新。当来自客户端的多个请求未完成时,来自服务器的单个更新可能会满足所有请求。

4. Input Protocol
4. 输入协议

The input side of the protocol is based on a standard workstation model of a keyboard and multi-button pointing device. Input events are simply sent to the server by the client whenever the user presses a key or pointer button, or whenever the pointing device is moved. These input events can also be synthesized from other non-standard I/O devices. For example, a pen-based handwriting recognition engine might generate keyboard events.

协议的输入端基于键盘和多按钮定点设备的标准工作站模型。只要用户按下键或指针按钮,或者移动指针设备,客户端就会将输入事件发送到服务器。这些输入事件也可以从其他非标准I/O设备合成。例如,基于笔的手写识别引擎可能会生成键盘事件。

5. Representation of Pixel Data
5. 像素数据的表示

Initial interaction between the RFB client and server involves a negotiation of the format and encoding of the pixel data that will be sent. This negotiation has been designed to make the job of the client as easy as possible. The server must always be able to supply pixel data in the form the client wants. However, if the client is able to cope equally with several different formats or encodings, it may choose one that is easier for the server to produce.

RFB客户端和服务器之间的初始交互涉及将要发送的像素数据的格式和编码的协商。此谈判旨在使客户的工作尽可能简单。服务器必须始终能够以客户端想要的形式提供像素数据。但是,如果客户机能够平等地处理几种不同的格式或编码,它可能会选择一种更易于服务器生成的格式或编码。

Pixel format refers to the representation of individual colors by pixel values. The most common pixel formats are 24-bit or 16-bit "true color", where bit-fields within the pixel value translate directly to red, green, and blue intensities, and 8-bit "color map" (palette) where the pixel values are indices into a 256-entry table that contains the actual RGB intensities.

像素格式是指通过像素值表示单个颜色。最常见的像素格式是24位或16位“真彩色”,其中像素值内的位字段直接转换为红色、绿色和蓝色强度,以及8位“颜色映射”(调色板),其中像素值索引到包含实际RGB强度的256项表中。

Encoding refers to the way that a rectangle of pixel data will be sent to the client. Every rectangle of pixel data is prefixed by a header giving the X,Y position of the rectangle on the screen, the width and height of the rectangle, and an encoding type which specifies the encoding of the pixel data. The data itself then follows using the specified encoding.

编码是指将矩形像素数据发送到客户端的方式。像素数据的每个矩形都有一个标题作为前缀,标题给出了矩形在屏幕上的X、Y位置、矩形的宽度和高度以及指定像素数据编码的编码类型。然后,数据本身使用指定的编码。

The encoding types defined at present are: Raw, CopyRect, RRE, TRLE, Hextile, and ZRLE. In practice, current servers use the ZRLE, TRLE, and CopyRect encodings since they provide the best compression for typical desktops. Clients generally also support Hextile, which was often used by older RFB servers that didn't support TRLE. See Section 7.7 for a description of each of the encodings.

目前定义的编码类型有:Raw、CopyRect、RRE、TRLE、Hextile和ZRLE。实际上,当前的服务器使用ZRLE、TRLE和CopyRect编码,因为它们为典型的台式机提供了最佳的压缩。客户端通常也支持Hextile,不支持TRLE的旧RFB服务器经常使用Hextile。有关每种编码的说明,请参见第7.7节。

6. Protocol Versions and Extensions
6. 协议版本和扩展

The RFB protocol has evolved through three published versions: 3.3, 3.7, and 3.8. This document primarily documents the final version 3.8; differences from the earlier versions, which are minor, are described in Appendix A. Under no circumstances should an implementation use a protocol version number other than one defined in this document. Over the years, different implementations of RFB have attempted to use different version numbers to add undocumented extensions, with the result being that to interoperate, any unknown 3.x version must be treated as 3.3, so it is not possible to add a 3.9 or higher version in a backward-compatible fashion. Future evolution of RFB will use 4.x version numbers.

RFB协议经过三个已发布版本的演变:3.3、3.7和3.8。本文件主要记录最终版本3.8;附录A中描述了与早期版本的细微差异。在任何情况下,实施都不得使用本文件中定义的协议版本号以外的协议版本号。多年来,RFB的不同实现尝试使用不同的版本号来添加未记录的扩展,其结果是为了互操作,任何未知的3.x版本都必须被视为3.3,因此不可能以向后兼容的方式添加3.9或更高版本。RFB的未来发展将使用4.x版本号。

It is not necessary to change the protocol version number to extend the protocol. The protocol can be extended within an existing version by:

扩展协议时无需更改协议版本号。可通过以下方式在现有版本内扩展协议:

New encodings A new encoding type can be added to the protocol relatively easily while maintaining compatibility with existing clients and servers. Existing servers will simply ignore requests for a new encoding that they don't support. Existing clients will never request the new encoding so will never see rectangles encoded that way.

新编码一种新的编码类型可以相对容易地添加到协议中,同时保持与现有客户端和服务器的兼容性。现有服务器只会忽略它们不支持的新编码请求。现有客户端永远不会请求新的编码,因此永远不会看到以这种方式编码的矩形。

Pseudo-encodings In addition to genuine encodings, a client can request a "pseudo-encoding" to declare to the server that it supports a certain extension to the protocol. A server that does not support the extension will simply ignore the pseudo-encoding. Note that this means the client must assume that the server does not support the extension until it gets some extension-specific confirmation from the server. See Section 7.8 for a description of current pseudo-encodings.

伪编码除了真正的编码之外,客户机还可以请求“伪编码”向服务器声明它支持协议的特定扩展。不支持扩展的服务器将忽略伪编码。注意,这意味着客户机必须假设服务器不支持扩展,直到它从服务器获得一些特定于扩展的确认。有关当前伪编码的说明,请参见第7.8节。

New security types Adding a new security type gives full flexibility in modifying the behavior of the protocol without sacrificing compatibility with existing clients and servers. A client and server that agree on a new security type can effectively talk whatever protocol they like after that -- it doesn't necessarily have to be anything like the RFB protocol.

新的安全类型添加新的安全类型可以在不牺牲与现有客户端和服务器的兼容性的情况下,在修改协议行为方面提供充分的灵活性。在一种新的安全类型上达成一致的客户机和服务器可以有效地讨论他们喜欢的任何协议——不一定是RFB协议。

See Section 8 for information on obtaining an ID for a new encoding or security type.

有关获取新编码或安全类型的ID的信息,请参见第8节。

7. Protocol Messages
7. 协议消息

The RFB protocol can operate over any reliable transport, either byte-stream or message based. It usually operates over a TCP/IP connection. There are three stages to the protocol. First is the handshaking phase, the purpose of which is to agree upon the protocol version and the type of security to be used. The second stage is an initialization phase where the client and server exchange ClientInit and ServerInit messages. The final stage is the normal protocol interaction. The client can send whichever messages it wants, and may receive messages from the server as a result. All these messages begin with a message-type byte, followed by message-specific data.

RFB协议可以在任何可靠的传输上运行,无论是字节流还是基于消息的传输。它通常通过TCP/IP连接进行操作。协议分为三个阶段。首先是握手阶段,其目的是商定协议版本和要使用的安全类型。第二阶段是初始化阶段,客户机和服务器在其中交换ClientInit和ServerInit消息。最后一个阶段是正常的协议交互。客户机可以发送它想要的任何消息,因此可能会从服务器接收消息。所有这些消息都以消息类型字节开头,后跟消息特定数据。

The following descriptions of protocol messages use the basic types U8, U16, U32, S8, S16, and S32. These represent, respectively, 8-, 16-, and 32-bit unsigned integers and 8-, 16-, and 32-bit signed integers. All multiple-byte integers (other than pixel values themselves) are in big endian order (most significant byte first). Some messages use arrays of the basic types, with the number of entries in the array determined from fields preceding the array.

以下协议消息的描述使用基本类型U8、U16、U32、S8、S16和S32。它们分别表示8位、16位和32位无符号整数以及8位、16位和32位有符号整数。所有多字节整数(像素值本身除外)都以大端顺序排列(最高有效字节优先)。有些消息使用基本类型的数组,数组中的条目数由数组前面的字段确定。

The type PIXEL means a pixel value of bytesPerPixel bytes, where bytesPerPixel is the number of bits-per-pixel divided by 8. The bits-per-pixel is agreed by the client and server, either in the ServerInit message (Section 7.3.2) or a SetPixelFormat message (Section 7.5.1). See Section 7.4 for the detailed description of the pixel format.

类型像素表示字节/像素字节的像素值,其中字节/像素是每像素的位数除以8。每像素位数由客户端和服务器在ServerInit消息(第7.3.2节)或SetPixelFormat消息(第7.5.1节)中商定。有关像素格式的详细说明,请参见第7.4节。

Several message formats include padding bits or bytes. For maximum compatibility, messages should be generated with padding set to zero, but message recipients should not assume padding has any particular value.

有几种消息格式包括填充位或字节。为获得最大兼容性,生成消息时应将填充设置为零,但消息收件人不应假定填充具有任何特定值。

7.1. Handshake Messages
7.1. 握手信息

When an RFB client and server first connect, they exchange a sequence of handshake messages that determine the protocol version, what type of connection security (if any) to use, a password check if the security type requires it, and some initialization information.

当RFB客户端和服务器首次连接时,它们交换一系列握手消息,这些消息确定协议版本、要使用的连接安全类型(如果有)、密码检查(如果安全类型需要)以及一些初始化信息。

7.1.1. ProtocolVersion Handshake
7.1.1. 协议版本握手

Handshaking begins by the server sending the client a ProtocolVersion message. This lets the client know which is the highest RFB protocol version number supported by the server. The client then replies with a similar message giving the version number of the protocol that should actually be used (which may be different to that quoted by the server). A client should never request a protocol version higher than that offered by the server. It is intended that both clients and servers may provide some level of backwards compatibility by this mechanism.

握手开始于服务器向客户端发送协议版本消息。这让客户端知道服务器支持的最高RFB协议版本号。然后,客户机回复类似的消息,给出实际应使用的协议版本号(可能与服务器引用的版本号不同)。客户机不应请求高于服务器提供的协议版本。客户机和服务器都可以通过这种机制提供某种程度的向后兼容性。

The only published protocol versions at this time are 3.3, 3.7, and 3.8. Other version numbers are reported by some servers and clients, but should be interpreted as 3.3 since they do not implement the different handshake in 3.7 or 3.8. Addition of a new encoding or pseudo-encoding type does not require a change in protocol version, since a server can simply ignore encodings it does not understand.

目前唯一发布的协议版本是3.3、3.7和3.8。其他版本号由一些服务器和客户端报告,但应解释为3.3,因为它们在3.7或3.8中没有实现不同的握手。添加新的编码或伪编码类型不需要更改协议版本,因为服务器可以忽略它不理解的编码。

The ProtocolVersion message consists of 12 bytes interpreted as a string of ASCII characters in the format "RFB xxx.yyy\n" where xxx and yyy are the major and minor version numbers, left-padded with zeros:

ProtocolVersion消息由12个字节组成,解释为格式为“RFB xxx.yyy\n”的ASCII字符字符串,其中xxx和yyy是主版本号和次版本号,左键用零填充:

RFB 003.008\n (hex 52 46 42 20 30 30 33 2e 30 30 38 0a)

RFB 003.008\n(十六进制52 46 42 20 30 33 2e 30 38 0a)

7.1.2. Security Handshake
7.1.2. 安全握手

Once the protocol version has been decided, the server and client must agree on the type of security to be used on the connection. The server lists the security types that it supports:

一旦确定了协议版本,服务器和客户端必须就连接上使用的安全类型达成一致。服务器列出了它支持的安全类型:

   +--------------------------+-------------+--------------------------+
   | No. of bytes             | Type        | Description              |
   |                          | [Value]     |                          |
   +--------------------------+-------------+--------------------------+
   | 1                        | U8          | number-of-security-types |
   | number-of-security-types | U8 array    | security-types           |
   +--------------------------+-------------+--------------------------+
        
   +--------------------------+-------------+--------------------------+
   | No. of bytes             | Type        | Description              |
   |                          | [Value]     |                          |
   +--------------------------+-------------+--------------------------+
   | 1                        | U8          | number-of-security-types |
   | number-of-security-types | U8 array    | security-types           |
   +--------------------------+-------------+--------------------------+
        

If the server listed at least one valid security type supported by the client, the client sends back a single byte indicating which security type is to be used on the connection:

如果服务器列出了客户端支持的至少一种有效的安全类型,则客户端会发回一个字节,指示要在连接上使用的安全类型:

              +--------------+--------------+---------------+
              | No. of bytes | Type [Value] | Description   |
              +--------------+--------------+---------------+
              | 1            | U8           | security-type |
              +--------------+--------------+---------------+
        
              +--------------+--------------+---------------+
              | No. of bytes | Type [Value] | Description   |
              +--------------+--------------+---------------+
              | 1            | U8           | security-type |
              +--------------+--------------+---------------+
        

If number-of-security-types is zero, then for some reason the connection failed (e.g., the server cannot support the desired protocol version). This is followed by a string describing the reason (where a string is specified as a length followed by that many ASCII characters):

如果安全类型数为零,则由于某种原因连接失败(例如,服务器无法支持所需的协议版本)。后面是一个描述原因的字符串(其中一个字符串指定为长度,后跟那么多ASCII字符):

             +---------------+--------------+---------------+
             | No. of bytes  | Type [Value] | Description   |
             +---------------+--------------+---------------+
             | 4             | U32          | reason-length |
             | reason-length | U8 array     | reason-string |
             +---------------+--------------+---------------+
        
             +---------------+--------------+---------------+
             | No. of bytes  | Type [Value] | Description   |
             +---------------+--------------+---------------+
             | 4             | U32          | reason-length |
             | reason-length | U8 array     | reason-string |
             +---------------+--------------+---------------+
        

The server closes the connection after sending the reason-string.

服务器在发送原因字符串后关闭连接。

The security types defined in this document are:

本文档中定义的安全类型包括:

                      +--------+--------------------+
                      | Number | Name               |
                      +--------+--------------------+
                      | 0      | Invalid            |
                      | 1      | None               |
                      | 2      | VNC Authentication |
                      +--------+--------------------+
        
                      +--------+--------------------+
                      | Number | Name               |
                      +--------+--------------------+
                      | 0      | Invalid            |
                      | 1      | None               |
                      | 2      | VNC Authentication |
                      +--------+--------------------+
        

Other security types exist but are not publicly documented.

存在其他安全类型,但未公开记录。

Once the security-type has been decided, data specific to that security-type follows (see Section 7.2 for details). At the end of the security handshaking phase, the protocol normally continues with the SecurityResult message.

一旦确定了安全类型,该安全类型的特定数据如下(详情见第7.2节)。在安全握手阶段结束时,协议通常会继续发送SecurityResult消息。

Note that after the security handshaking phase, it is possible that further communication is over an encrypted or otherwise altered channel if the two ends agree on an extended security type beyond the ones described here.

注意,在安全握手阶段之后,如果两端同意超出此处描述的扩展安全类型,则有可能通过加密或以其他方式改变的信道进行进一步通信。

7.1.3. SecurityResult Handshake
7.1.3. 安全结果握手

The server sends a word to inform the client whether the security handshaking was successful.

服务器发送一个字来通知客户端安全握手是否成功。

               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 4            | U32          | status:     |
               |              | 0            | OK          |
               |              | 1            | failed      |
               +--------------+--------------+-------------+
        
               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 4            | U32          | status:     |
               |              | 0            | OK          |
               |              | 1            | failed      |
               +--------------+--------------+-------------+
        

If successful, the protocol passes to the initialization phase (Section 7.3).

如果成功,协议将进入初始化阶段(第7.3节)。

If unsuccessful, the server sends a string describing the reason for the failure, and then closes the connection:

如果失败,服务器将发送一个字符串,描述失败的原因,然后关闭连接:

             +---------------+--------------+---------------+
             | No. of bytes  | Type [Value] | Description   |
             +---------------+--------------+---------------+
             | 4             | U32          | reason-length |
             | reason-length | U8 array     | reason-string |
             +---------------+--------------+---------------+
        
             +---------------+--------------+---------------+
             | No. of bytes  | Type [Value] | Description   |
             +---------------+--------------+---------------+
             | 4             | U32          | reason-length |
             | reason-length | U8 array     | reason-string |
             +---------------+--------------+---------------+
        
7.2. Security Types
7.2. 安全类型

Two security types are defined here.

这里定义了两种安全类型。

7.2.1. None
7.2.1. 没有一个

No authentication is needed. The protocol continues with the SecurityResult message.

不需要身份验证。协议继续执行SecurityResult消息。

7.2.2. VNC Authentication
7.2.2. VNC身份验证

VNC authentication is to be used. The server sends a random 16-byte challenge:

将使用VNC身份验证。服务器发送一个随机的16字节质询:

               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 16           | U8           | challenge   |
               +--------------+--------------+-------------+
        
               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 16           | U8           | challenge   |
               +--------------+--------------+-------------+
        

The client encrypts the challenge with DES, using a password supplied by the user as the key. To form the key, the password is truncated to eight characters, or padded with null bytes on the right. The client then sends the resulting 16-byte response:

客户端使用用户提供的密码作为密钥,使用DES对质询进行加密。要形成密钥,密码将被截断为八个字符,或在右侧填充空字节。然后,客户端发送生成的16字节响应:

               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 16           | U8           | response    |
               +--------------+--------------+-------------+
        
               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 16           | U8           | response    |
               +--------------+--------------+-------------+
        

The protocol continues with the SecurityResult message.

协议继续执行SecurityResult消息。

This type of authentication is known to be cryptographically weak and is not intended for use on untrusted networks. Many implementations will want to use stronger security, such as running the session over an encrypted channel provided by IPsec [RFC4301] or SSH [RFC4254].

已知这种类型的身份验证在加密方面很弱,不适用于不受信任的网络。许多实现都希望使用更强的安全性,例如通过IPsec[RFC4301]或SSH[RFC4254]提供的加密通道运行会话。

7.3. Initialization Messages
7.3. 初始化消息

Once the client and server agree on and perhaps validate a security type, the protocol passes to the initialization stage. The client sends a ClientInit message. Then, the server sends a ServerInit message.

一旦客户机和服务器同意并可能验证安全类型,协议就进入初始化阶段。客户端发送ClientInit消息。然后,服务器发送一条ServerInit消息。

7.3.1. ClientInit
7.3.1. 阴蒂
               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 1            | U8           | shared-flag |
               +--------------+--------------+-------------+
        
               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 1            | U8           | shared-flag |
               +--------------+--------------+-------------+
        

Shared-flag is non-zero (true) if the server should try to share the desktop by leaving other clients connected, and zero (false) if it should give exclusive access to this client by disconnecting all other clients.

如果服务器应通过保持其他客户端的连接来尝试共享桌面,则Shared flag为非零(true);如果服务器应通过断开所有其他客户端的连接以独占方式访问此客户端,则Shared flag为零(false)。

7.3.2. ServerInit
7.3.2. 服务器初始化

After receiving the ClientInit message, the server sends a ServerInit message. This tells the client the width and height of the server's framebuffer, its pixel format, and the name associated with the desktop:

在接收到ClientInit消息后,服务器发送一条ServerInit消息。这会告诉客户端服务器帧缓冲区的宽度和高度、像素格式以及与桌面关联的名称:

      +--------------+--------------+------------------------------+
      | No. of bytes | Type [Value] | Description                  |
      +--------------+--------------+------------------------------+
      | 2            | U16          | framebuffer-width in pixels  |
      | 2            | U16          | framebuffer-height in pixels |
      | 16           | PIXEL_FORMAT | server-pixel-format          |
      | 4            | U32          | name-length                  |
      | name-length  | U8 array     | name-string                  |
      +--------------+--------------+------------------------------+
        
      +--------------+--------------+------------------------------+
      | No. of bytes | Type [Value] | Description                  |
      +--------------+--------------+------------------------------+
      | 2            | U16          | framebuffer-width in pixels  |
      | 2            | U16          | framebuffer-height in pixels |
      | 16           | PIXEL_FORMAT | server-pixel-format          |
      | 4            | U32          | name-length                  |
      | name-length  | U8 array     | name-string                  |
      +--------------+--------------+------------------------------+
        

Server-pixel-format specifies the server's natural pixel format. This pixel format will be used unless the client requests a different format using the SetPixelFormat message (Section 7.5.1).

服务器像素格式指定服务器的自然像素格式。除非客户使用SetPixelFormat消息(第7.5.1节)请求不同的格式,否则将使用该像素格式。

7.4. Pixel Format Data Structure
7.4. 像素格式数据结构

Several server-to-client messages include a PIXEL_FORMAT, a 16-byte structure that describes the way a pixel is transmitted.

一些服务器到客户端的消息包括像素_格式,这是一种描述像素传输方式的16字节结构。

             +--------------+--------------+-----------------+
             | No. of bytes | Type [Value] | Description     |
             +--------------+--------------+-----------------+
             | 1            | U8           | bits-per-pixel  |
             | 1            | U8           | depth           |
             | 1            | U8           | big-endian-flag |
             | 1            | U8           | true-color-flag |
             | 2            | U16          | red-max         |
             | 2            | U16          | green-max       |
             | 2            | U16          | blue-max        |
             | 1            | U8           | red-shift       |
             | 1            | U8           | green-shift     |
             | 1            | U8           | blue-shift      |
             | 3            |              | padding         |
             +--------------+--------------+-----------------+
        
             +--------------+--------------+-----------------+
             | No. of bytes | Type [Value] | Description     |
             +--------------+--------------+-----------------+
             | 1            | U8           | bits-per-pixel  |
             | 1            | U8           | depth           |
             | 1            | U8           | big-endian-flag |
             | 1            | U8           | true-color-flag |
             | 2            | U16          | red-max         |
             | 2            | U16          | green-max       |
             | 2            | U16          | blue-max        |
             | 1            | U8           | red-shift       |
             | 1            | U8           | green-shift     |
             | 1            | U8           | blue-shift      |
             | 3            |              | padding         |
             +--------------+--------------+-----------------+
        

Bits-per-pixel is the number of bits used for each pixel value on the wire. This must be greater than or equal to the depth, which is the number of useful bits in the pixel value. Currently bits-per-pixel must be 8, 16, or 32. Big-endian-flag is non-zero (true) if multi-byte pixels are interpreted as big endian. Although the depth should be consistent with the bits-per-pixel and the various -max values, clients do not use it when interpreting pixel data.

每像素位数是导线上每个像素值使用的位数。这必须大于或等于深度,深度是像素值中有用的位数。当前,每个像素的位必须是8、16或32。如果多字节像素被解释为Big-endian,则Big-endian标志为非零(true)。虽然深度应该与每像素位数和各种最大值一致,但客户端在解释像素数据时不使用深度。

If true-color-flag is non-zero (true), then the last six items specify how to extract the red, green, and blue intensities from the pixel value. Red-max is the maximum red value and must be 2^N - 1, where N is the number of bits used for red. Note the -max values are always in big endian order. Red-shift is the number of shifts needed

如果真彩色标志为非零(true),则最后六项指定如何从像素值提取红色、绿色和蓝色强度。Red max是最大红色值,必须为2^N-1,其中N是用于红色的位数。请注意,-max值始终以大端顺序排列。“红移”是所需的班次数

to get the red value in a pixel to the least significant bit. Green-max, green-shift, blue-max, and blue-shift are similar for green and blue. For example, to find the red value (between 0 and red-max) from a given pixel, do the following:

获取像素中的红色值至最低有效位。绿色最大值、绿色偏移、蓝色最大值和蓝色偏移对于绿色和蓝色类似。例如,要查找给定像素的红色值(介于0和红色最大值之间),请执行以下操作:

o Swap the pixel value according to big-endian-flag, e.g., if big-endian-flag is zero (false) and host byte order is big endian, then swap.

o 根据big-endian标志交换像素值,例如,如果big-endian标志为零(false),主机字节顺序为big-endian,则交换。

o Shift right by red-shift.

o 按红移右移。

o AND with red-max (in host byte order).

o 和红色最大值(按主机字节顺序)。

If true-color-flag is zero (false), then the server uses pixel values that are not directly composed from the red, green, and blue intensities, but serve as indices into a color map. Entries in the color map are set by the server using the SetColorMapEntries message (See Section 7.6.2).

如果真彩色标志为零(false),则服务器将使用像素值,这些像素值不是直接由红色、绿色和蓝色强度组成的,而是用作颜色贴图的索引。颜色映射中的条目由服务器使用SetColorMapEntries消息设置(参见第7.6.2节)。

7.5. Client-to-Server Messages
7.5. 客户端到服务器消息

The client-to-server message types defined in this document are:

本文档中定义的客户端到服务器消息类型包括:

                   +--------+--------------------------+
                   | Number | Name                     |
                   +--------+--------------------------+
                   | 0      | SetPixelFormat           |
                   | 2      | SetEncodings             |
                   | 3      | FramebufferUpdateRequest |
                   | 4      | KeyEvent                 |
                   | 5      | PointerEvent             |
                   | 6      | ClientCutText            |
                   +--------+--------------------------+
        
                   +--------+--------------------------+
                   | Number | Name                     |
                   +--------+--------------------------+
                   | 0      | SetPixelFormat           |
                   | 2      | SetEncodings             |
                   | 3      | FramebufferUpdateRequest |
                   | 4      | KeyEvent                 |
                   | 5      | PointerEvent             |
                   | 6      | ClientCutText            |
                   +--------+--------------------------+
        

Other message types exist but are not publicly documented. Before sending a message other than those described in this document, a client must have determined that the server supports the relevant extension by receiving an appropriate extension-specific confirmation from the server.

存在其他消息类型,但未公开记录。在发送本文档中所述以外的消息之前,客户机必须通过从服务器接收到适当的特定于扩展的确认来确定服务器支持相关扩展。

7.5.1. SetPixelFormat
7.5.1. 设置像素格式

A SetPixelFormat message sets the format in which pixel values should be sent in FramebufferUpdate messages. If the client does not send a SetPixelFormat message, then the server sends pixel values in its natural format as specified in the ServerInit message (Section 7.3.2).

SetPixelFormat消息设置在FramebufferUpdate消息中发送像素值的格式。如果客户端未发送SetPixelFormat消息,则服务器将按照ServerInit消息(第7.3.2节)中指定的自然格式发送像素值。

If true-color-flag is zero (false), then this indicates that a "color map" is to be used. The server can set any of the entries in the color map using the SetColorMapEntries message (Section 7.6.2). Immediately after the client has sent this message, the contents of the color map are undefined, even if entries had previously been set by the server.

如果真彩色标志为零(false),则表示将使用“颜色映射”。服务器可以使用SetColorMapEntries消息(第7.6.2节)设置颜色映射中的任何条目。客户机发送此消息后,颜色映射的内容立即未定义,即使服务器以前已设置了条目。

              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [0]       | message-type |
              | 3            |              | padding      |
              | 16           | PIXEL_FORMAT | pixel-format |
              +--------------+--------------+--------------+
        
              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [0]       | message-type |
              | 3            |              | padding      |
              | 16           | PIXEL_FORMAT | pixel-format |
              +--------------+--------------+--------------+
        

PIXEL_FORMAT is as described in Section 7.4.

像素_格式如第7.4节所述。

7.5.2. SetEncodings
7.5.2. 集合编码

A SetEncodings message sets the encoding types in which pixel data can be sent by the server. The order of the encoding types given in this message is a hint by the client as to its preference (the first encoding specified being most preferred). The server may or may not choose to make use of this hint. Pixel data may always be sent in raw encoding even if not specified explicitly here.

SetEncodings消息设置服务器可以发送像素数据的编码类型。此消息中给出的编码类型顺序是客户机对其首选项的提示(指定的第一种编码是最首选的)。服务器可能会也可能不会选择使用此提示。即使此处未明确指定,像素数据也可能始终以原始编码发送。

In addition to genuine encodings, a client can request "pseudo-encodings" to declare to the server that it supports certain extensions to the protocol. A server that does not support the extension will simply ignore the pseudo-encoding. Note that this means the client must assume that the server does not support the extension until it gets some extension-specific confirmation from the server.

除了真正的编码之外,客户机还可以请求“伪编码”向服务器声明它支持协议的某些扩展。不支持扩展的服务器将忽略伪编码。注意,这意味着客户机必须假设服务器不支持扩展,直到它从服务器获得一些特定于扩展的确认。

See Section 7.7 for a description of each encoding and Section 7.8 for the meaning of pseudo-encodings.

参见第7.7节了解每种编码的说明,参见第7.8节了解伪编码的含义。

           +--------------+--------------+---------------------+
           | No. of bytes | Type [Value] | Description         |
           +--------------+--------------+---------------------+
           | 1            | U8 [2]       | message-type        |
           | 1            |              | padding             |
           | 2            | U16          | number-of-encodings |
           +--------------+--------------+---------------------+
        
           +--------------+--------------+---------------------+
           | No. of bytes | Type [Value] | Description         |
           +--------------+--------------+---------------------+
           | 1            | U8 [2]       | message-type        |
           | 1            |              | padding             |
           | 2            | U16          | number-of-encodings |
           +--------------+--------------+---------------------+
        

This is followed by number-of-encodings repetitions of the following:

然后是以下编码的重复次数:

              +--------------+--------------+---------------+
              | No. of bytes | Type [Value] | Description   |
              +--------------+--------------+---------------+
              | 4            | S32          | encoding-type |
              +--------------+--------------+---------------+
        
              +--------------+--------------+---------------+
              | No. of bytes | Type [Value] | Description   |
              +--------------+--------------+---------------+
              | 4            | S32          | encoding-type |
              +--------------+--------------+---------------+
        
7.5.3. FramebufferUpdateRequest
7.5.3. FramebufferUpdateRequest

A FramebufferUpdateRequest message notifies the server that the client is interested in the area of the framebuffer specified by x-position, y-position, width, and height. The server usually responds to a FramebufferUpdateRequest by sending a FramebufferUpdate. A single FramebufferUpdate may be sent in reply to several FramebufferUpdateRequests.

FramebufferUpdateRequest消息通知服务器客户端对由x位置、y位置、宽度和高度指定的帧缓冲区区域感兴趣。服务器通常通过发送FramebufferUpdate来响应FramebufferUpdateRequest。可以发送单个FramebufferUpdate以响应多个FrameBufferUpdateRequest。

The server assumes that the client keeps a copy of all parts of the framebuffer in which it is interested. This means that normally the server only needs to send incremental updates to the client.

服务器假定客户端保留其感兴趣的帧缓冲区所有部分的副本。这意味着服务器通常只需要向客户端发送增量更新。

If the client has lost the contents of a particular area that it needs, then the client sends a FramebufferUpdateRequest with incremental set to zero (false). This requests that the server send the entire contents of the specified area as soon as possible. The area will not be updated using the CopyRect encoding.

如果客户端丢失了它所需的特定区域的内容,则客户端发送增量设置为零(false)的FramebufferUpdateRequest。这要求服务器尽快发送指定区域的全部内容。该区域将不会使用CopyRect编码进行更新。

If the client has not lost any contents of the area in which it is interested, then it sends a FramebufferUpdateRequest with incremental set to non-zero (true). If and when there are changes to the specified area of the framebuffer, the server will send a FramebufferUpdate. Note that there may be an indefinite period between the FramebufferUpdateRequest and the FramebufferUpdate.

如果客户端没有丢失它感兴趣的区域的任何内容,那么它将发送一个FramebufferUpdateRequest,增量设置为非零(true)。如果帧缓冲区的指定区域发生更改,服务器将发送帧缓冲区更新。请注意,FramebufferUpdateRequest和FramebufferUpdate之间可能有一段不确定的时间。

In the case of a fast client, the client may want to regulate the rate at which it sends incremental FramebufferUpdateRequests to avoid excessive network traffic.

对于快速客户端,客户端可能希望调整其发送增量FramebufferUpdateRequests的速率,以避免过多的网络流量。

              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [3]       | message-type |
              | 1            | U8           | incremental  |
              | 2            | U16          | x-position   |
              | 2            | U16          | y-position   |
              | 2            | U16          | width        |
              | 2            | U16          | height       |
              +--------------+--------------+--------------+
        
              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [3]       | message-type |
              | 1            | U8           | incremental  |
              | 2            | U16          | x-position   |
              | 2            | U16          | y-position   |
              | 2            | U16          | width        |
              | 2            | U16          | height       |
              +--------------+--------------+--------------+
        
7.5.4. KeyEvent
7.5.4. 键盘事件

A KeyEvent message indicates a key press or release. Down-flag is non-zero (true) if the key is now pressed, and zero (false) if it is now released. The key itself is specified using the "keysym" values defined by the X Window System, even if the client or server is not running the X Window System.

KeyEvent消息表示按键或释放。如果现在按下该键,则向下标志为非零(true),如果现在松开该键,则向下标志为零(false)。即使客户机或服务器未运行X窗口系统,也使用X窗口系统定义的“keysym”值指定密钥本身。

              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [4]       | message-type |
              | 1            | U8           | down-flag    |
              | 2            |              | padding      |
              | 4            | U32          | key          |
              +--------------+--------------+--------------+
        
              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [4]       | message-type |
              | 1            | U8           | down-flag    |
              | 2            |              | padding      |
              | 4            | U32          | key          |
              +--------------+--------------+--------------+
        

For most ordinary keys, the keysym is the same as the corresponding ASCII value. For full details, see [XLIBREF] or see the header file <X11/keysymdef.h> in the X Window System distribution. Some other common keys are:

对于大多数普通键,keysym与相应的ASCII值相同。有关详细信息,请参阅[XLIBREF]或X Window系统发行版中的头文件<X11/keysymdef.h>。其他一些常用键包括:

                 +-----------------+--------------------+
                 | Key name        | Keysym value (hex) |
                 +-----------------+--------------------+
                 | BackSpace       | 0xff08             |
                 | Tab             | 0xff09             |
                 | Return or Enter | 0xff0d             |
                 | Escape          | 0xff1b             |
                 | Insert          | 0xff63             |
                 | Delete          | 0xffff             |
                 | Home            | 0xff50             |
                 | End             | 0xff57             |
                 | Page Up         | 0xff55             |
                 | Page Down       | 0xff56             |
                 | Left            | 0xff51             |
                 | Up              | 0xff52             |
                 | Right           | 0xff53             |
                 | Down            | 0xff54             |
                 | F1              | 0xffbe             |
                 | F2              | 0xffbf             |
                 | F3              | 0xffc0             |
                 | F4              | 0xffc1             |
                 | ...             | ...                |
                 | F12             | 0xffc9             |
                 | Shift (left)    | 0xffe1             |
                 | Shift (right)   | 0xffe2             |
                 | Control (left)  | 0xffe3             |
                 | Control (right) | 0xffe4             |
                 | Meta (left)     | 0xffe7             |
                 | Meta (right)    | 0xffe8             |
                 | Alt (left)      | 0xffe9             |
                 | Alt (right)     | 0xffea             |
                 +-----------------+--------------------+
        
                 +-----------------+--------------------+
                 | Key name        | Keysym value (hex) |
                 +-----------------+--------------------+
                 | BackSpace       | 0xff08             |
                 | Tab             | 0xff09             |
                 | Return or Enter | 0xff0d             |
                 | Escape          | 0xff1b             |
                 | Insert          | 0xff63             |
                 | Delete          | 0xffff             |
                 | Home            | 0xff50             |
                 | End             | 0xff57             |
                 | Page Up         | 0xff55             |
                 | Page Down       | 0xff56             |
                 | Left            | 0xff51             |
                 | Up              | 0xff52             |
                 | Right           | 0xff53             |
                 | Down            | 0xff54             |
                 | F1              | 0xffbe             |
                 | F2              | 0xffbf             |
                 | F3              | 0xffc0             |
                 | F4              | 0xffc1             |
                 | ...             | ...                |
                 | F12             | 0xffc9             |
                 | Shift (left)    | 0xffe1             |
                 | Shift (right)   | 0xffe2             |
                 | Control (left)  | 0xffe3             |
                 | Control (right) | 0xffe4             |
                 | Meta (left)     | 0xffe7             |
                 | Meta (right)    | 0xffe8             |
                 | Alt (left)      | 0xffe9             |
                 | Alt (right)     | 0xffea             |
                 +-----------------+--------------------+
        

The interpretation of keysyms is a complex area. In order to be as widely interoperable as possible, the following guidelines should be followed:

钥匙符号的解释是一个复杂的领域。为了尽可能广泛地进行互操作,应遵循以下准则:

o The "shift state" (i.e., whether either of the Shift keysyms is down) should only be used as a hint when interpreting a keysym. For example, on a US keyboard the '#' character is shifted, but on a UK keyboard it is not. A server with a US keyboard receiving a '#' character from a client with a UK keyboard will not have been sent any shift presses. In this case, it is likely that the server will internally need to simulate a shift press on its local system in order to get a '#' character and not a '3'.

o 在解释键符号时,“移位状态”(即,移位键符号中的任何一个是否向下)只能用作提示。例如,在美国键盘上“#”字符会移位,但在英国键盘上则不会。使用美国键盘的服务器从使用英国键盘的客户端接收“#”字符时,不会发送任何shift键。在这种情况下,服务器可能在内部需要在其本地系统上模拟shift键,以便获得“#”字符而不是“3”。

o The difference between upper and lower case keysyms is significant. This is unlike some of the keyboard processing in the X Window System that treats them as the same. For example, a server receiving an upper case 'A' keysym without any shift presses should interpret it as an upper case 'A'. Again this may involve an internal simulated shift press.

o 大写和小写键符号之间的差异是显著的。这与X窗口系统中的某些键盘处理不同,X窗口系统将它们视为相同的处理。例如,在不按shift键的情况下接收大写“a”键ym的服务器应将其解释为大写“a”。同样,这可能涉及一个内部模拟换档压力机。

o Servers should ignore "lock" keysyms such as CapsLock and NumLock where possible. Instead, they should interpret each character-based keysym according to its case.

o 服务器应尽可能忽略“锁定”键符号,如CapsLock和NumLock。相反,他们应该根据其大小写解释每个基于字符的keysym。

o Unlike Shift, the state of modifier keys such as Control and Alt should be taken as modifying the interpretation of other keysyms. Note that there are no keysyms for ASCII control characters such as Ctrl-A -- these should be generated by clients sending a Control press followed by an 'a' press.

o 与Shift不同,修改器键(如Control和Alt)的状态应视为修改其他键符号的解释。请注意,ASCII控制字符(如Ctrl-A)没有键符号——这些字符应该由客户端先发送控制键,然后再发送“A”键来生成。

o On a client where modifiers like Control and Alt can also be used to generate character-based keysyms, the client may need to send extra "release" events in order that the keysym is interpreted correctly. For example, on a German PC keyboard, Ctrl-Alt-Q generates the '@' character. In this case, the client needs to send simulated release events for Control and Alt in order that the '@' character is interpreted correctly, since Ctrl-Alt-@ may mean something completely different to the server.

o 在客户机上,还可以使用诸如Control和Alt之类的修饰符生成基于字符的键值符号,客户机可能需要发送额外的“release”事件,以便正确解释键值符号。例如,在德语PC键盘上,Ctrl-Alt-Q生成“@”字符。在这种情况下,客户端需要为Control和Alt发送模拟的释放事件,以便正确解释“@”字符,因为Ctrl-Alt-@对服务器的含义可能完全不同。

o There is no universal standard for "backward tab" in the X Window System. On some systems shift+tab gives the keysym "ISO_Left_Tab", on others it gives a private "BackTab" keysym, and on others it gives "Tab" and applications tell from the shift state that it means backward-tab rather than forward-tab. In the RFB protocol, the latter approach is preferred. Clients should generate a shifted Tab rather than ISO_Left_Tab. However, to be backwards-compatible with existing clients, servers should also recognize ISO_Left_Tab as meaning a shifted Tab.

o 在X窗口系统中没有“向后选项卡”的通用标准。在某些系统上,shift+tab给出键ym“ISO_Left_tab”,在另一些系统上,它给出私有的“BackTab”键ym,在另一些系统上,它给出“tab”,应用程序从shift状态得知,它意味着向后tab,而不是向前tab。在RFB协议中,后一种方法是首选的。客户端应该生成一个移位的选项卡,而不是ISO_Left_选项卡。然而,为了向后兼容现有客户机,服务器还应该将ISO_Left_选项卡识别为一个移位的选项卡。

o Modern versions of the X Window System handle keysyms for Unicode characters, consisting of the Unicode character with the hex 1000000 bit set. For maximum compatibility, if a key has both a Unicode and a legacy encoding, clients should send the legacy encoding.

o 现代版本的X Window系统处理Unicode字符的键符号,包括设置了十六进制1000000位的Unicode字符。为了获得最大的兼容性,如果密钥同时具有Unicode和传统编码,则客户端应发送传统编码。

o Some systems give a special interpretation to key combinations such as Ctrl-Alt-Delete. RFB clients typically provide a menu or toolbar function to send such key combinations. The RFB protocol does not treat them specially; to send Ctrl-Alt-Delete, the client sends the key presses for left or right Control, left or right

o 有些系统对组合键(如Ctrl-Alt-Delete)进行特殊解释。RFB客户端通常提供一个菜单或工具栏功能来发送这样的组合键。RFB协议没有特别对待它们;要发送Ctrl-Alt-Delete,客户端会发送向左或向右控制键(向左或向右)

Alt, and Delete, followed by the key releases. Many RFB servers accept Shift-Ctrl-Alt-Delete as a synonym for Ctrl-Alt-Delete that can be entered directly from the keyboard.

Alt和Delete,然后按键释放。许多RFB服务器接受Shift-Ctrl-Alt-Delete作为可以直接从键盘输入的Ctrl-Alt-Delete的同义词。

7.5.5. PointerEvent
7.5.5. 指针事件

A PointerEvent message indicates either pointer movement or a pointer button press or release. The pointer is now at (x-position, y-position), and the current state of buttons 1 to 8 are represented by bits 0 to 7 of button-mask, respectively; 0 means up, 1 means down (pressed).

指针事件消息表示指针移动或指针按钮按下或释放。指针现在位于(x位置,y位置),按钮1至8的当前状态分别由按钮掩码的位0至7表示;0表示向上,1表示向下(按下)。

On a conventional mouse, buttons 1, 2, and 3 correspond to the left, middle, and right buttons on the mouse. On a wheel mouse, each step of the wheel upwards is represented by a press and release of button 4, and each step downwards is represented by a press and release of button 5.

在传统鼠标上,按钮1、2和3对应于鼠标上的左、中、右按钮。在滚轮鼠标上,滚轮向上的每一步都由按下和释放按钮4表示,向下的每一步都由按下和释放按钮5表示。

              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [5]       | message-type |
              | 1            | U8           | button-mask  |
              | 2            | U16          | x-position   |
              | 2            | U16          | y-position   |
              +--------------+--------------+--------------+
        
              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [5]       | message-type |
              | 1            | U8           | button-mask  |
              | 2            | U16          | x-position   |
              | 2            | U16          | y-position   |
              +--------------+--------------+--------------+
        
7.5.6. ClientCutText
7.5.6. ClientCutText

RFB provides limited support for synchronizing the "cut buffer" of selected text between client and server. This message tells the server that the client has new ISO 8859-1 (Latin-1) text in its cut buffer. Ends of lines are represented by the newline character (hex 0a) alone. No carriage-return (hex 0d) is used. There is no way to transfer text outside the Latin-1 character set.

RFB为在客户端和服务器之间同步所选文本的“剪切缓冲区”提供了有限的支持。此消息告诉服务器,客户端的剪切缓冲区中有新的ISO 8859-1(拉丁语-1)文本。行尾仅由换行符(十六进制0a)表示。未使用回车符(十六进制0d)。无法将文本传输到拉丁-1字符集之外。

              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [6]       | message-type |
              | 3            |              | padding      |
              | 4            | U32          | length       |
              | length       | U8 array     | text         |
              +--------------+--------------+--------------+
        
              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [6]       | message-type |
              | 3            |              | padding      |
              | 4            | U32          | length       |
              | length       | U8 array     | text         |
              +--------------+--------------+--------------+
        
7.6. Server-to-Client Messages
7.6. 服务器到客户端消息

The server-to-client message types defined in this document are:

本文档中定义的服务器到客户端消息类型为:

                      +--------+--------------------+
                      | Number | Name               |
                      +--------+--------------------+
                      | 0      | FramebufferUpdate  |
                      | 1      | SetColorMapEntries |
                      | 2      | Bell               |
                      | 3      | ServerCutText      |
                      +--------+--------------------+
        
                      +--------+--------------------+
                      | Number | Name               |
                      +--------+--------------------+
                      | 0      | FramebufferUpdate  |
                      | 1      | SetColorMapEntries |
                      | 2      | Bell               |
                      | 3      | ServerCutText      |
                      +--------+--------------------+
        

Other private message types exist but are not publicly documented. Before sending a message other than those described in this document a server must have determined that the client supports the relevant extension by receiving some extension-specific confirmation from the client -- usually a request for a given pseudo-encoding.

存在其他私有消息类型,但未公开记录。在发送本文档中描述的消息之外的消息之前,服务器必须通过从客户端接收一些特定于扩展的确认来确定客户端支持相关扩展,通常是对给定伪编码的请求。

7.6.1. FramebufferUpdate
7.6.1. 帧缓冲区更新

A framebuffer update consists of a sequence of rectangles of pixel data that the client should put into its framebuffer. It is sent in response to a FramebufferUpdateRequest from the client. Note that there may be an indefinite period between the FramebufferUpdateRequest and the FramebufferUpdate.

帧缓冲区更新由一系列矩形像素数据组成,客户端应将这些数据放入其帧缓冲区。它是响应来自客户端的FramebufferUpdateRequest而发送的。请注意,FramebufferUpdateRequest和FramebufferUpdate之间可能有一段不确定的时间。

          +--------------+--------------+----------------------+
          | No. of bytes | Type [Value] | Description          |
          +--------------+--------------+----------------------+
          | 1            | U8 [0]       | message-type         |
          | 1            |              | padding              |
          | 2            | U16          | number-of-rectangles |
          +--------------+--------------+----------------------+
        
          +--------------+--------------+----------------------+
          | No. of bytes | Type [Value] | Description          |
          +--------------+--------------+----------------------+
          | 1            | U8 [0]       | message-type         |
          | 1            |              | padding              |
          | 2            | U16          | number-of-rectangles |
          +--------------+--------------+----------------------+
        

This header is followed by number-of-rectangles rectangles of pixel data. Each rectangle starts with a rectangle header:

该标题后面是像素数据的矩形数。每个矩形都以矩形标题开头:

              +--------------+--------------+---------------+
              | No. of bytes | Type [Value] | Description   |
              +--------------+--------------+---------------+
              | 2            | U16          | x-position    |
              | 2            | U16          | y-position    |
              | 2            | U16          | width         |
              | 2            | U16          | height        |
              | 4            | S32          | encoding-type |
              +--------------+--------------+---------------+
        
              +--------------+--------------+---------------+
              | No. of bytes | Type [Value] | Description   |
              +--------------+--------------+---------------+
              | 2            | U16          | x-position    |
              | 2            | U16          | y-position    |
              | 2            | U16          | width         |
              | 2            | U16          | height        |
              | 4            | S32          | encoding-type |
              +--------------+--------------+---------------+
        

The rectangle header is followed by the pixel data in the specified encoding. See Section 7.7 for the format of the data for each encoding and Section 7.8 for the meaning of pseudo-encodings.

矩形标题后面是指定编码的像素数据。每种编码的数据格式见第7.7节,伪编码的含义见第7.8节。

7.6.2. SetColorMapEntries
7.6.2. SetColorMapEntries

When the pixel format uses a "color map", this message tells the client that the specified pixel values should be mapped to the given RGB values. Note that this message may only update part of the color map. This message should not be sent by the server until after the client has sent at least one FramebufferUpdateRequest, and only when the agreed pixel format uses a color map.

当像素格式使用“颜色映射”时,此消息告诉客户端指定的像素值应映射到给定的RGB值。请注意,此消息可能仅更新部分颜色映射。只有在客户端发送了至少一个FramebufferUpdateRequest之后,并且只有在商定的像素格式使用颜色映射时,服务器才应发送此消息。

Color map values are always 16 bits, with the range of values running from 0 to 65535, regardless of the display hardware in use. The color map value for white, for example, is 65535,65535,65535.

颜色映射值始终为16位,值的范围从0到65535,与使用的显示硬件无关。例如,白色的颜色贴图值为655356553565535。

The message starts with a header describing the range of colormap entries to be updated.

消息以描述要更新的colormap条目范围的标题开始。

            +--------------+--------------+------------------+
            | No. of bytes | Type [Value] | Description      |
            +--------------+--------------+------------------+
            | 1            | U8 [1]       | message-type     |
            | 1            |              | padding          |
            | 2            | U16          | first-color      |
            | 2            | U16          | number-of-colors |
            +--------------+--------------+------------------+
        
            +--------------+--------------+------------------+
            | No. of bytes | Type [Value] | Description      |
            +--------------+--------------+------------------+
            | 1            | U8 [1]       | message-type     |
            | 1            |              | padding          |
            | 2            | U16          | first-color      |
            | 2            | U16          | number-of-colors |
            +--------------+--------------+------------------+
        

This header is followed by number-of-colors RGB values, each of which is in this format:

此标题后面是颜色数RGB值,每个值的格式如下:

               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 2            | U16          | red         |
               | 2            | U16          | green       |
               | 2            | U16          | blue        |
               +--------------+--------------+-------------+
        
               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 2            | U16          | red         |
               | 2            | U16          | green       |
               | 2            | U16          | blue        |
               +--------------+--------------+-------------+
        
7.6.3. Bell
7.6.3. 钟

A Bell message makes an audible signal on the client if it provides one.

如果客户机上提供了铃声信息,则铃声信息会发出声音信号。

              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [2]       | message-type |
              +--------------+--------------+--------------+
        
              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [2]       | message-type |
              +--------------+--------------+--------------+
        
7.6.4. ServerCutText
7.6.4. 服务器插文

The server has new ISO 8859-1 (Latin-1) text in its cut buffer. Ends of lines are represented by the newline character (hex 0a) alone. No carriage-return (hex 0d) is used. There is no way to transfer text outside the Latin-1 character set.

服务器的剪切缓冲区中有新的ISO 8859-1(拉丁语-1)文本。行尾仅由换行符(十六进制0a)表示。未使用回车符(十六进制0d)。无法将文本传输到拉丁-1字符集之外。

              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [3]       | message-type |
              | 3            |              | padding      |
              | 4            | U32          | length       |
              | length       | U8 array     | text         |
              +--------------+--------------+--------------+
        
              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8 [3]       | message-type |
              | 3            |              | padding      |
              | 4            | U32          | length       |
              | length       | U8 array     | text         |
              +--------------+--------------+--------------+
        
7.7. Encodings
7.7. 编码

The encodings defined in this document are:

本文件中定义的编码为:

                 +--------+-----------------------------+
                 | Number | Name                        |
                 +--------+-----------------------------+
                 | 0      | Raw                         |
                 | 1      | CopyRect                    |
                 | 2      | RRE                         |
                 | 5      | Hextile                     |
                 | 15     | TRLE                        |
                 | 16     | ZRLE                        |
                 | -239   | Cursor pseudo-encoding      |
                 | -223   | DesktopSize pseudo-encoding |
                 +--------+-----------------------------+
        
                 +--------+-----------------------------+
                 | Number | Name                        |
                 +--------+-----------------------------+
                 | 0      | Raw                         |
                 | 1      | CopyRect                    |
                 | 2      | RRE                         |
                 | 5      | Hextile                     |
                 | 15     | TRLE                        |
                 | 16     | ZRLE                        |
                 | -239   | Cursor pseudo-encoding      |
                 | -223   | DesktopSize pseudo-encoding |
                 +--------+-----------------------------+
        

Other encoding types exist but are not publicly documented.

存在其他编码类型,但未公开记录。

7.7.1. Raw Encoding
7.7.1. 原始编码

The simplest encoding type is raw pixel data. In this case, the data consists of width*height pixel values (where width and height are the width and height of the rectangle). The values simply represent each pixel in left-to-right scan line order. All RFB clients must be able to handle pixel data in this raw encoding, and RFB servers should only produce raw encoding unless the client specifically asks for some other encoding type.

最简单的编码类型是原始像素数据。在这种情况下,数据由宽度*高度像素值组成(其中宽度和高度是矩形的宽度和高度)。这些值只是以从左到右的扫描线顺序表示每个像素。所有RFB客户机必须能够处理此原始编码中的像素数据,并且RFB服务器应仅生成原始编码,除非客户机明确要求其他编码类型。

        +----------------------------+--------------+-------------+
        | No. of bytes               | Type [Value] | Description |
        +----------------------------+--------------+-------------+
        | width*height*bytesPerPixel | PIXEL array  | pixels      |
        +----------------------------+--------------+-------------+
        
        +----------------------------+--------------+-------------+
        | No. of bytes               | Type [Value] | Description |
        +----------------------------+--------------+-------------+
        | width*height*bytesPerPixel | PIXEL array  | pixels      |
        +----------------------------+--------------+-------------+
        
7.7.2. CopyRect Encoding
7.7.2. CopyRect编码

The CopyRect (copy rectangle) encoding is a very simple and efficient encoding that can be used when the client already has the same pixel data elsewhere in its framebuffer. The encoding on the wire simply consists of an X,Y coordinate. This gives a position in the framebuffer from which the client can copy the rectangle of pixel data. This can be used in a variety of situations, the most common of which are when the user moves a window across the screen, and when the contents of a window are scrolled.

CopyRect(复制矩形)编码是一种非常简单和高效的编码,当客户端在其帧缓冲区中的其他位置已经具有相同的像素数据时,可以使用这种编码。导线上的编码仅由X,Y坐标组成。这在帧缓冲区中提供了一个位置,客户端可以从中复制像素数据的矩形。这可以用于多种情况,最常见的情况是用户在屏幕上移动窗口,以及滚动窗口内容。

             +--------------+--------------+----------------+
             | No. of bytes | Type [Value] | Description    |
             +--------------+--------------+----------------+
             | 2            | U16          | src-x-position |
             | 2            | U16          | src-y-position |
             +--------------+--------------+----------------+
        
             +--------------+--------------+----------------+
             | No. of bytes | Type [Value] | Description    |
             +--------------+--------------+----------------+
             | 2            | U16          | src-x-position |
             | 2            | U16          | src-y-position |
             +--------------+--------------+----------------+
        

For maximum compatibility, the source rectangle of a CopyRect should not include pixels updated by previous entries in the same FramebufferUpdate message.

为获得最大兼容性,CopyRect的源矩形不应包含由同一FramebufferUpdate消息中的先前条目更新的像素。

7.7.3. RRE Encoding
7.7.3. RRE编码

Note: RRE encoding is obsolescent. In general, ZRLE and TRLE encodings are more compact.

注:RRE编码已过时。一般来说,ZRLE和TRLE编码更紧凑。

RRE stands for rise-and-run-length encoding. As its name implies, it is essentially a two-dimensional analogue of run-length encoding. RRE-encoded rectangles arrive at the client in a form that can be

RRE代表上升和游程编码。顾名思义,它本质上是游程编码的二维模拟。RRE编码的矩形以可编辑的形式到达客户端

rendered immediately by the simplest of graphics engines. RRE is not appropriate for complex desktops, but can be useful in some situations.

由最简单的图形引擎立即渲染。RRE不适用于复杂的桌面,但在某些情况下可能很有用。

The basic idea behind RRE is the partitioning of a rectangle of pixel data into rectangular subregions (subrectangles) each of which consists of pixels of a single value, and the union of which comprises the original rectangular region. The near-optimal partition of a given rectangle into such subrectangles is relatively easy to compute.

RRE背后的基本思想是将像素数据的矩形划分为矩形子区域(子矩形),每个子区域由单个值的像素组成,并且像素的并集包含原始矩形区域。将给定矩形近似最优地划分为这样的子矩形相对容易计算。

The encoding consists of a background pixel value, Vb (typically the most prevalent pixel value in the rectangle) and a count N, followed by a list of N subrectangles, each of which consists of a tuple <v,x,y,w,h> where v (which should be different from Vb) is the pixel value, (x,y) are the coordinates of the subrectangle relative to the top-left corner of the rectangle, and (w,h) are the width and height of the subrectangle. The client can render the original rectangle by drawing a filled rectangle of the background pixel value and then drawing a filled rectangle corresponding to each subrectangle.

编码由背景像素值Vb(通常是矩形中最常用的像素值)和计数N组成,然后是N个子矩形列表,每个子矩形由元组<v,x,y,w,h>组成,其中v(应不同于Vb)是像素值,(x,y)是子矩形相对于矩形左上角的坐标,(w,h)是子矩形的宽度和高度。客户端可以通过绘制背景像素值的填充矩形,然后绘制对应于每个子矩形的填充矩形来渲染原始矩形。

On the wire, the data begins with the header:

在导线上,数据以标题开头:

        +---------------+--------------+-------------------------+
        | No. of bytes  | Type [Value] | Description             |
        +---------------+--------------+-------------------------+
        | 4             | U32          | number-of-subrectangles |
        | bytesPerPixel | PIXEL        | background-pixel-value  |
        +---------------+--------------+-------------------------+
        
        +---------------+--------------+-------------------------+
        | No. of bytes  | Type [Value] | Description             |
        +---------------+--------------+-------------------------+
        | 4             | U32          | number-of-subrectangles |
        | bytesPerPixel | PIXEL        | background-pixel-value  |
        +---------------+--------------+-------------------------+
        

This is followed by number-of-subrectangles instances of the following structure:

然后是以下结构的子矩形实例数:

          +---------------+--------------+---------------------+
          | No. of bytes  | Type [Value] | Description         |
          +---------------+--------------+---------------------+
          | bytesPerPixel | PIXEL        | subrect-pixel-value |
          | 2             | U16          | x-position          |
          | 2             | U16          | y-position          |
          | 2             | U16          | width               |
          | 2             | U16          | height              |
          +---------------+--------------+---------------------+
        
          +---------------+--------------+---------------------+
          | No. of bytes  | Type [Value] | Description         |
          +---------------+--------------+---------------------+
          | bytesPerPixel | PIXEL        | subrect-pixel-value |
          | 2             | U16          | x-position          |
          | 2             | U16          | y-position          |
          | 2             | U16          | width               |
          | 2             | U16          | height              |
          +---------------+--------------+---------------------+
        
7.7.4. Hextile Encoding
7.7.4. 六进制编码

Note: Hextile encoding is obsolescent. In general, ZRLE and TRLE encodings are more compact.

注意:十六进制编码已过时。一般来说,ZRLE和TRLE编码更紧凑。

Hextile is a variation on RRE. Rectangles are split up into 16x16 tiles, allowing the dimensions of the subrectangles to be specified in 4 bits each, 16 bits in total. The rectangle is split into tiles starting at the top left going in left-to-right, top-to-bottom order. The encoded contents of the tiles simply follow one another in the predetermined order. If the width of the whole rectangle is not an exact multiple of 16, then the width of the last tile in each row will be correspondingly smaller. Similarly, if the height of the whole rectangle is not an exact multiple of 16, then the height of each tile in the final row will also be smaller.

Hextile是RRE的一个变体。矩形被分割成16x16块,允许子矩形的尺寸以4位为单位指定,总共16位。矩形从左上角开始按从左到右、从上到下的顺序拆分为平铺。瓦片的编码内容只是按照预定顺序彼此跟随。如果整个矩形的宽度不是16的精确倍数,则每行中最后一个平铺的宽度将相应地更小。类似地,如果整个矩形的高度不是16的精确倍数,则最后一行中每个瓷砖的高度也将更小。

Each tile is either encoded as raw pixel data, or as a variation on RRE. Each tile has a background pixel value, as before. The background pixel value does not need to be explicitly specified for a given tile if it is the same as the background of the previous tile. However, the background pixel value may not be carried over if the previous tile was raw. If all of the subrectangles of a tile have the same pixel value, this can be specified once as a foreground pixel value for the whole tile. As with the background, the foreground pixel value can be left unspecified, meaning it is carried over from the previous tile. The foreground pixel value may not be carried over if the previous tile was raw or had the SubrectsColored bit set. It may, however, be carried over from a previous tile with the AnySubrects bit clear, as long as that tile itself carried over a valid foreground from its previous tile.

每个分片要么作为原始像素数据编码,要么作为RRE的变体编码。与前面一样,每个磁贴都有一个背景像素值。如果给定磁贴的背景与上一个磁贴的背景相同,则无需为其明确指定背景像素值。但是,如果前一个磁贴是原始的,则背景像素值可能不会被带入。如果平铺的所有子矩形具有相同的像素值,则可以将其指定为整个平铺的前景像素值。与背景一样,前景像素值可以保持未指定状态,这意味着它是从上一个平铺中继承的。如果前一个磁贴为原始磁贴或设置了子矩形着色位,则前景像素值可能不会被带入。然而,只要该块本身从其先前的块中携带了有效的前景,它就可以从先前的块中携带AnySubrects位清除。

The data consists of each tile encoded in order. Each tile begins with a subencoding type byte, which is a mask made up of a number of bits:

数据由按顺序编码的每个磁贴组成。每个磁贴以子编码类型字节开始,该字节是由若干位组成的掩码:

           +--------------+--------------+---------------------+
           | No. of bytes | Type [Value] | Description         |
           +--------------+--------------+---------------------+
           | 1            | U8           | subencoding-mask:   |
           |              | [1]          | Raw                 |
           |              | [2]          | BackgroundSpecified |
           |              | [4]          | ForegroundSpecified |
           |              | [8]          | AnySubrects         |
           |              | [16]         | SubrectsColored     |
           +--------------+--------------+---------------------+
        
           +--------------+--------------+---------------------+
           | No. of bytes | Type [Value] | Description         |
           +--------------+--------------+---------------------+
           | 1            | U8           | subencoding-mask:   |
           |              | [1]          | Raw                 |
           |              | [2]          | BackgroundSpecified |
           |              | [4]          | ForegroundSpecified |
           |              | [8]          | AnySubrects         |
           |              | [16]         | SubrectsColored     |
           +--------------+--------------+---------------------+
        

If the Raw bit is set, then the other bits are irrelevant; width*height pixel values follow (where width and height are the width and height of the tile). Otherwise, the other bits in the mask are as follows:

如果设置了原始位,则其他位不相关;随后是宽度*高度像素值(其中宽度和高度是平铺的宽度和高度)。否则,掩码中的其他位如下所示:

BackgroundSpecified If set, a pixel value of bytesPerPixel bytes follows and specifies the background color for this tile. The first non-raw tile in a rectangle must have this bit set. If this bit isn't set, then the background is the same as the last tile.

BackgroundSpecified如果设置,则后面会有一个字节/像素字节的像素值,并指定此平铺的背景色。矩形中的第一个非原始平铺必须设置此位。如果未设置此位,则背景与最后一个平铺相同。

ForegroundSpecified If set, a pixel value of bytesPerPixel bytes follows and specifies the foreground color to be used for all subrectangles in this tile.

ForegroundSpecified如果设置,将跟随bytesPerPixel字节的像素值,并指定用于此平铺中所有子矩形的前景色。

If this bit is set, then the SubrectsColored bit must be zero.

如果设置了此位,则子矩形着色位必须为零。

AnySubrects If set, a single byte follows and gives the number of subrectangles following. If not set, there are no subrectangles (i.e., the whole tile is just solid background color).

AnySubrects如果设置,则后面跟着一个字节,并给出后面的子矩形数。如果未设置,则不存在子矩形(即,整个平铺仅为纯色背景色)。

SubrectsColored If set, then each subrectangle is preceded by a pixel value giving the color of that subrectangle, so a subrectangle is:

子矩形着色如果设置,则每个子矩形前面都有一个像素值,该像素值表示该子矩形的颜色,因此子矩形为:

          +---------------+--------------+---------------------+
          | No. of bytes  | Type [Value] | Description         |
          +---------------+--------------+---------------------+
          | bytesPerPixel | PIXEL        | subrect-pixel-value |
          | 1             | U8           | x-and-y-position    |
          | 1             | U8           | width-and-height    |
          +---------------+--------------+---------------------+
        
          +---------------+--------------+---------------------+
          | No. of bytes  | Type [Value] | Description         |
          +---------------+--------------+---------------------+
          | bytesPerPixel | PIXEL        | subrect-pixel-value |
          | 1             | U8           | x-and-y-position    |
          | 1             | U8           | width-and-height    |
          +---------------+--------------+---------------------+
        

If not set, all subrectangles are the same color -- the foreground color; if the ForegroundSpecified bit wasn't set, then the foreground is the same as the last tile. A subrectangle is:

如果未设置,则所有子矩形都是相同的颜色——前景色;如果未设置foreground指定的位,则前景与最后一个平铺相同。子矩形是:

            +--------------+--------------+------------------+
            | No. of bytes | Type [Value] | Description      |
            +--------------+--------------+------------------+
            | 1            | U8           | x-and-y-position |
            | 1            | U8           | width-and-height |
            +--------------+--------------+------------------+
        
            +--------------+--------------+------------------+
            | No. of bytes | Type [Value] | Description      |
            +--------------+--------------+------------------+
            | 1            | U8           | x-and-y-position |
            | 1            | U8           | width-and-height |
            +--------------+--------------+------------------+
        

The position and size of each subrectangle is specified in two bytes, x-and-y-position and width-and-height. The most significant 4 bits of x-and-y-position specify the X position, the least significant specify the Y position. The most significant 4 bits of width-and-height specify the width minus 1, the least significant specify the height minus 1.

每个子矩形的位置和大小以两个字节指定,x和y位置以及宽度和高度。x和y位置的最高有效4位指定x位置,最低有效4位指定y位置。宽度和高度的最高有效4位指定宽度减1,最低有效4位指定高度减1。

7.7.5. TRLE
7.7.5. TRLE

TRLE stands for Tiled Run-Length Encoding, and combines tiling, palettization, and run-length encoding. The rectangle is divided into tiles of 16x16 pixels in left-to-right, top-to-bottom order, similar to Hextile. If the width of the rectangle is not an exact multiple of 16, then the width of the last tile in each row is smaller, and if the height of the rectangle is not an exact multiple of 16, then the height of each tile in the final row is smaller.

TRLE代表平铺运行长度编码,它结合了平铺、调色板和运行长度编码。矩形按从左到右、从上到下的顺序划分为16x16像素的平铺,类似于六角平铺。如果矩形的宽度不是16的精确倍数,则每行中最后一个磁贴的宽度较小,如果矩形的高度不是16的精确倍数,则最后一行中每个磁贴的高度较小。

TRLE makes use of a new type CPIXEL (compressed pixel). This is the same as a PIXEL for the agreed pixel format, except as a special case, it uses a more compact format if true-color-flag is non-zero, bits-per-pixel is 32, depth is 24 or less, and all of the bits making up the red, green, and blue intensities fit in either the least significant 3 bytes or the most significant 3 bytes. If all of these are the case, a CPIXEL is only 3 bytes long, and contains the least significant or the most significant 3 bytes as appropriate. bytesPerCPixel is the number of bytes in a CPIXEL.

TRLE使用了一种新型的CPIXEL(压缩像素)。这与约定像素格式的像素相同,但特殊情况除外,如果真彩色标志为非零,每像素位为32,深度为24或更少,并且构成红色、绿色和蓝色强度的所有位适合最低有效3字节或最高有效3字节,则使用更紧凑的格式。如果所有这些都是这种情况,则CPIXEL的长度仅为3个字节,并且包含最低有效或最高有效的3个字节(视情况而定)。bytesPerCPixel是CPIXEL中的字节数。

Each tile begins with a subencoding type byte. The top bit of this byte is set if the tile has been run-length encoded, clear otherwise. The bottom 7 bits indicate the size of the palette used: zero means no palette, 1 means that the tile is of a single color, and 2 to 127 indicate a palette of that size. The special subencoding values 129 and 127 indicate that the palette is to be reused from the last tile that had a palette, with and without RLE, respectively.

每个磁贴都以子编码类型字节开始。如果磁贴已进行运行长度编码,则设置此字节的顶部位,否则清除。底部7位表示所用调色板的大小:0表示没有调色板,1表示平铺为单一颜色,2到127表示该大小的调色板。特殊子编码值129和127分别表示调色板将从具有调色板的最后一个分片(带和不带RLE)重用。

Note: in this discussion, the div(a,b) function means the result of dividing a/b truncated to an integer.

注意:在本讨论中,div(a,b)函数表示将a/b除以截断为整数的结果。

The possible values of subencoding are:

子编码的可能值为:

0: Raw pixel data. width*height pixel values follow (where width and height are the width and height of the tile):

0:原始像素数据。下面是宽度*高度像素值(其中宽度和高度是平铺的宽度和高度):

       +-----------------------------+--------------+-------------+
       | No. of bytes                | Type [Value] | Description |
       +-----------------------------+--------------+-------------+
       | width*height*BytesPerCPixel | CPIXEL array | pixels      |
       +-----------------------------+--------------+-------------+
        
       +-----------------------------+--------------+-------------+
       | No. of bytes                | Type [Value] | Description |
       +-----------------------------+--------------+-------------+
       | width*height*BytesPerCPixel | CPIXEL array | pixels      |
       +-----------------------------+--------------+-------------+
        

1: A solid tile consisting of a single color. The pixel value follows:

1:由单一颜色组成的实心瓷砖。像素值如下所示:

              +----------------+--------------+-------------+
              | No. of bytes   | Type [Value] | Description |
              +----------------+--------------+-------------+
              | bytesPerCPixel | CPIXEL       | pixelValue  |
              +----------------+--------------+-------------+
        
              +----------------+--------------+-------------+
              | No. of bytes   | Type [Value] | Description |
              +----------------+--------------+-------------+
              | bytesPerCPixel | CPIXEL       | pixelValue  |
              +----------------+--------------+-------------+
        

2 to 16: Packed palette types. The paletteSize is the value of the subencoding, which is followed by the palette, consisting of paletteSize pixel values. The packed pixels follow, with each pixel represented as a bit field yielding a zero-based index into the palette. For paletteSize 2, a 1-bit field is used; for paletteSize 3 or 4, a 2-bit field is used; and for paletteSize from 5 to 16, a 4-bit field is used. The bit fields are packed into bytes, with the most significant bits representing the leftmost pixel (i.e., big endian). For tiles not a multiple of 8, 4, or 2 pixels wide (as appropriate), padding bits are used to align each row to an exact number of bytes.

2到16:打包调色板类型。paletteSize是子编码的值,后接调色板,由paletteSize像素值组成。随后是压缩像素,每个像素表示为一个位字段,在调色板中产生一个从零开始的索引。对于选项板大小2,使用1位字段;对于选项板3或4,使用2位字段;对于从5到16的选项板,使用4位字段。位字段压缩为字节,最高有效位表示最左边的像素(即大端)。对于宽度不是8、4或2像素倍数(视情况而定)的分幅,填充位用于将每行与精确的字节数对齐。

       +----------------------------+--------------+--------------+
       | No. of bytes               | Type [Value] | Description  |
       +----------------------------+--------------+--------------+
       | paletteSize*bytesPerCPixel | CPIXEL array | palette      |
       | m                          | U8 array     | packedPixels |
       +----------------------------+--------------+--------------+
        
       +----------------------------+--------------+--------------+
       | No. of bytes               | Type [Value] | Description  |
       +----------------------------+--------------+--------------+
       | paletteSize*bytesPerCPixel | CPIXEL array | palette      |
       | m                          | U8 array     | packedPixels |
       +----------------------------+--------------+--------------+
        

where m is the number of bytes representing the packed pixels. For paletteSize of 2, this is div(width+7,8)*height; for paletteSize of 3 or 4, this is div(width+3,4)*height; or for paletteSize of 5 to 16, this is div(width+1,2)*height.

其中m是表示压缩像素的字节数。对于2的选项板,这是div(宽度+7,8)*高度;对于3或4的选项板,这是div(宽度+3,4)*高度;对于5到16的选项板,这是div(宽度+1,2)*高度。

17 to 126: Unused. (Packed palettes of these sizes would offer no advantage over palette RLE).

17至126:未使用。(这些尺寸的压缩调色板与调色板RLE相比没有任何优势)。

127: Packed palette with the palette reused from the previous tile. The subencoding byte is followed by the packed pixels as described above for packed palette types.

127:使用从上一个互动程序重用的调色板打包调色板。子编码字节后面紧跟压缩像素,如上所述,用于压缩调色板类型。

128: Plain RLE. The data consists of a number of runs, repeated until the tile is done. Runs may continue from the end of one row to the beginning of the next. Each run is represented by a single pixel value followed by the length of the run. The length is represented as one or more bytes. The length is calculated as one more than the sum of all the bytes representing the length. Any byte value other than 255 indicates the final byte. So for

128:普通RLE。数据由多次运行组成,重复运行,直到平铺完成。运行可以从一行的末尾继续到下一行的开头。每个运行由单个像素值表示,后跟运行长度。长度表示为一个或多个字节。计算长度时,长度比表示长度的所有字节之和多1个。255以外的任何字节值都表示最后一个字节。所以

example, length 1 is represented as [0], 255 as [254], 256 as [255,0], 257 as [255,1], 510 as [255,254], 511 as [255,255,0], and so on.

例如,长度1表示为[0],255表示为[254],256表示为[255,0],257表示为[255,1],510表示为[255254],511表示为[255255,0],依此类推。

    +-------------------------+--------------+-----------------------+
    | No. of bytes            | Type [Value] | Description           |
    +-------------------------+--------------+-----------------------+
    | bytesPerCPixel          | CPIXEL       | pixelValue            |
    | div(runLength - 1, 255) | U8 array     | 255                   |
    | 1                       | U8           | (runLength-1) mod 255 |
    +-------------------------+--------------+-----------------------+
        
    +-------------------------+--------------+-----------------------+
    | No. of bytes            | Type [Value] | Description           |
    +-------------------------+--------------+-----------------------+
    | bytesPerCPixel          | CPIXEL       | pixelValue            |
    | div(runLength - 1, 255) | U8 array     | 255                   |
    | 1                       | U8           | (runLength-1) mod 255 |
    +-------------------------+--------------+-----------------------+
        

129: Palette RLE with the palette reused from the previous tile. Followed by a number of runs, repeated until the tile is done, as described below for 130 to 255.

129:调色板RLE,调色板从上一个互动程序重复使用。接着是多次运行,重复运行,直到平铺完成,如下所述,运行130到255次。

   130 to 255:  Palette RLE.  Followed by the palette, consisting of
      paletteSize = (subencoding - 128) pixel values:
        
   130 to 255:  Palette RLE.  Followed by the palette, consisting of
      paletteSize = (subencoding - 128) pixel values:
        
        +----------------------------+--------------+-------------+
        | No. of bytes               | Type [Value] | Description |
        +----------------------------+--------------+-------------+
        | paletteSize*bytesPerCPixel | CPIXEL array | palette     |
        +----------------------------+--------------+-------------+
        
        +----------------------------+--------------+-------------+
        | No. of bytes               | Type [Value] | Description |
        +----------------------------+--------------+-------------+
        | paletteSize*bytesPerCPixel | CPIXEL array | palette     |
        +----------------------------+--------------+-------------+
        

Following the palette is, as with plain RLE, a number of runs, repeated until the tile is done. A run of length one is represented simply by a palette index:

与普通RLE一样,调色板后面会重复多次运行,直到平铺完成。长度为1的管路仅由调色板索引表示:

              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8           | paletteIndex |
              +--------------+--------------+--------------+
        
              +--------------+--------------+--------------+
              | No. of bytes | Type [Value] | Description  |
              +--------------+--------------+--------------+
              | 1            | U8           | paletteIndex |
              +--------------+--------------+--------------+
        

A run of length more than one is represented by a palette index with the top bit set, followed by the length of the run as for plain RLE.

长度超过1的行程由调色板索引表示,该索引具有顶部位集,后跟与普通RLE相同的行程长度。

    +-------------------------+--------------+-----------------------+
    | No. of bytes            | Type [Value] | Description           |
    +-------------------------+--------------+-----------------------+
    | 1                       | U8           | paletteIndex + 128    |
    | div(runLength - 1, 255) | U8 array     | 255                   |
    | 1                       | U8           | (runLength-1) mod 255 |
    +-------------------------+--------------+-----------------------+
        
    +-------------------------+--------------+-----------------------+
    | No. of bytes            | Type [Value] | Description           |
    +-------------------------+--------------+-----------------------+
    | 1                       | U8           | paletteIndex + 128    |
    | div(runLength - 1, 255) | U8 array     | 255                   |
    | 1                       | U8           | (runLength-1) mod 255 |
    +-------------------------+--------------+-----------------------+
        
7.7.6. ZRLE
7.7.6. 兹勒

ZRLE stands for Zlib (see [RFC1950] and [RFC1951]) Run-Length Encoding, and combines an encoding similar to TRLE with zlib compression. On the wire, the rectangle begins with a 4-byte length field, and is followed by that many bytes of zlib-compressed data. A single zlib "stream" object is used for a given RFB protocol connection, so that ZRLE rectangles must be encoded and decoded strictly in order.

ZRLE代表Zlib(参见[RFC1950]和[RFC1951])运行长度编码,并将类似于TRLE的编码与Zlib压缩相结合。在线路上,矩形以一个4字节长度的字段开始,然后是许多字节的zlib压缩数据。一个zlib“stream”对象用于给定的RFB协议连接,因此ZRLE矩形必须严格按顺序编码和解码。

               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 4            | U32          | length      |
               | length       | U8 array     | zlibData    |
               +--------------+--------------+-------------+
        
               +--------------+--------------+-------------+
               | No. of bytes | Type [Value] | Description |
               +--------------+--------------+-------------+
               | 4            | U32          | length      |
               | length       | U8 array     | zlibData    |
               +--------------+--------------+-------------+
        

The zlibData when uncompressed represents tiles in left-to-right, top-to-bottom order, similar to TRLE, but with a tile size of 64x64 pixels. If the width of the rectangle is not an exact multiple of 64, then the width of the last tile in each row is smaller, and if the height of the rectangle is not an exact multiple of 64, then the height of each tile in the final row is smaller.

未压缩时的zlibData表示从左到右、从上到下的分幅,与TRLE类似,但分幅大小为64x64像素。如果矩形的宽度不是64的精确倍数,则每行中最后一个磁贴的宽度较小,如果矩形的高度不是64的精确倍数,则最后一行中每个磁贴的高度较小。

The tiles are encoded in exactly the same way as TRLE, except that subencoding may not take the values 127 or 129, i.e., palettes cannot be reused between tiles.

瓷砖的编码方式与TRLE完全相同,只是子编码可能不采用127或129的值,即调色板不能在瓷砖之间重复使用。

The server flushes the zlib stream to a byte boundary at the end of each ZRLE-encoded rectangle. It need not flush the stream between tiles within a rectangle. Since the zlibData for a single rectangle can potentially be quite large, clients can incrementally decode and interpret the zlibData but must not assume that encoded tile data is byte aligned.

服务器将zlib流刷新到每个ZRLE编码矩形末尾的字节边界。它不需要在矩形内的瓷砖之间刷新流。由于单个矩形的zlibData可能相当大,因此客户端可以增量解码和解释zlibData,但不能假设编码的磁贴数据是字节对齐的。

7.8. Pseudo-Encodings
7.8. 伪编码

An update rectangle with a "pseudo-encoding" does not directly represent pixel data but instead allows the server to send arbitrary data to the client. How this data is interpreted depends on the pseudo-encoding.

带有“伪编码”的更新矩形并不直接表示像素数据,而是允许服务器向客户端发送任意数据。如何解释这些数据取决于伪编码。

7.8.1. Cursor Pseudo-Encoding
7.8.1. 游标伪编码

A client that requests the Cursor pseudo-encoding is declaring that it is capable of drawing a pointer cursor locally. This can significantly improve perceived performance over slow links. The server sets the cursor shape by sending a rectangle with the Cursor

请求游标伪编码的客户端声明它能够在本地绘制指针游标。这可以显著提高慢速链接的感知性能。服务器通过发送带有光标的矩形来设置光标形状

pseudo-encoding as part of an update. The rectangle's x-position and y-position indicate the hotspot of the cursor, and width and height indicate the width and height of the cursor in pixels. The data consists of width*height raw pixel values followed by a shape bitmask, with one bit corresponding to each pixel in the cursor rectangle. The bitmask consists of left-to-right, top-to-bottom scan lines, where each scan line is padded to a whole number of bytes, the number being div(width+7,8). Within each byte, the most significant bit represents the leftmost pixel; a bit set to 1 means the corresponding pixel in the cursor is valid.

作为更新的一部分的伪编码。矩形的x位置和y位置表示光标的热点,宽度和高度表示光标的宽度和高度(以像素为单位)。数据由宽度*高度原始像素值和形状位掩码组成,其中一位对应于光标矩形中的每个像素。位掩码由从左到右、从上到下的扫描行组成,其中每个扫描行填充为整数字节,数字为div(宽度+7,8)。在每个字节中,最高有效位表示最左边的像素;位设置为1表示光标中对应的像素有效。

       +----------------------------+--------------+---------------+
       | No. of bytes               | Type [Value] | Description   |
       +----------------------------+--------------+---------------+
       | width*height*bytesPerPixel | PIXEL array  | cursor-pixels |
       | div(width+7,8)*height      | U8 array     | bitmask       |
       +----------------------------+--------------+---------------+
        
       +----------------------------+--------------+---------------+
       | No. of bytes               | Type [Value] | Description   |
       +----------------------------+--------------+---------------+
       | width*height*bytesPerPixel | PIXEL array  | cursor-pixels |
       | div(width+7,8)*height      | U8 array     | bitmask       |
       +----------------------------+--------------+---------------+
        
7.8.2. DesktopSize Pseudo-Encoding
7.8.2. 桌面大小伪编码

A client that requests the DesktopSize pseudo-encoding is declaring that it is capable of coping with a change in the framebuffer width and height. The server changes the desktop size by sending a rectangle with the DesktopSize pseudo-encoding as the last rectangle in an update. The rectangle's x-position and y-position are ignored, and width and height indicate the new width and height of the framebuffer.

请求DesktopSize伪编码的客户端声明它能够处理帧缓冲区宽度和高度的更改。服务器通过发送一个带有DesktopSize伪编码的矩形作为更新中的最后一个矩形来更改桌面大小。矩形的x位置和y位置将被忽略,宽度和高度表示帧缓冲区的新宽度和高度。

There is no further data associated with the rectangle. After changing the desktop size, the server must assume that the client no longer has the previous framebuffer contents. This will usually result in a complete update of the framebuffer at the next update. However, for maximum interoperability with existing servers the client should preserve the top-left portion of the framebuffer between the old and new sizes.

没有与矩形关联的其他数据。更改桌面大小后,服务器必须假定客户端不再具有以前的帧缓冲区内容。这通常会导致在下次更新时完全更新帧缓冲区。但是,为了与现有服务器实现最大程度的互操作性,客户端应在新旧大小之间保留帧缓冲区的左上部分。

8. IANA Considerations
8. IANA考虑

IANA has allocated port 5900 to the RFB protocol. The other port numbers mentioned in Section 2 are called out for historical context and do not match IANA allocations.

IANA已将端口5900分配给RFB协议。第2节中提到的其他端口号是根据历史上下文调用的,与IANA分配不匹配。

Future assignments to the IANA registries created by this specification are to be made through either "Expert Review" or "IESG Approval" (if there is no currently appointed expert) as defined in [RFC5226].

按照[RFC5226]中的定义,本规范创建的IANA注册的未来分配将通过“专家审查”或“IESG批准”(如果当前没有指定专家)进行。

8.1. RFB Security Types
8.1. RFB安全类型
8.1.1. Registry Name
8.1.1. 注册表名

The name of this registry is "Remote Framebuffer Security Types".

此注册表的名称为“远程帧缓冲区安全类型”。

8.1.2. Registry Contents
8.1.2. 注册表内容

IANA established a registry for security types that are used with the RFB protocol.

IANA为RFB协议使用的安全类型建立了一个注册表。

The initial entries in the registry are:

注册表中的初始条目为:

     +------------+-------------------------+-----------------------+
     | Number     | Name                    | References            |
     +------------+-------------------------+-----------------------+
     | 0          | Invalid                 | (this document)       |
     | 1          | None                    | (this document)       |
     | 2          | VNC Authentication      | (this document)       |
     | 3 to 15    | RealVNC                 | (historic assignment) |
     | 16         | Tight                   | (historic assignment) |
     | 17         | Ultra                   | (historic assignment) |
     | 18         | TLS                     | (historic assignment) |
     | 19         | VeNCrypt                | (historic assignment) |
     | 20         | GTK-VNC SASL            | (historic assignment) |
     | 21         | MD5 hash authentication | (historic assignment) |
     | 22         | Colin Dean xvp          | (historic assignment) |
     | 128 to 255 | RealVNC                 | (historic assignment) |
     +------------+-------------------------+-----------------------+
        
     +------------+-------------------------+-----------------------+
     | Number     | Name                    | References            |
     +------------+-------------------------+-----------------------+
     | 0          | Invalid                 | (this document)       |
     | 1          | None                    | (this document)       |
     | 2          | VNC Authentication      | (this document)       |
     | 3 to 15    | RealVNC                 | (historic assignment) |
     | 16         | Tight                   | (historic assignment) |
     | 17         | Ultra                   | (historic assignment) |
     | 18         | TLS                     | (historic assignment) |
     | 19         | VeNCrypt                | (historic assignment) |
     | 20         | GTK-VNC SASL            | (historic assignment) |
     | 21         | MD5 hash authentication | (historic assignment) |
     | 22         | Colin Dean xvp          | (historic assignment) |
     | 128 to 255 | RealVNC                 | (historic assignment) |
     +------------+-------------------------+-----------------------+
        
8.2. Client-to-Server Message Types
8.2. 客户端到服务器的消息类型
8.2.1. Registry Name
8.2.1. 注册表名

The name of this registry is "Remote Framebuffer Client-to-Server Message Types".

此注册表的名称为“远程帧缓冲区客户端到服务器消息类型”。

8.2.2. Registry Contents
8.2.2. 注册表内容

IANA established a registry for client-to-server message types that are used with the RFB protocol.

IANA为RFB协议使用的客户端到服务器消息类型建立了注册表。

The initial entries in the registry are:

注册表中的初始条目为:

     +--------+------------------------------+-----------------------+
     | Number | Name                         | References            |
     +--------+------------------------------+-----------------------+
     | 0      | SetPixelFormat               | (this document)       |
     | 2      | SetEncodings                 | (this document)       |
     | 3      | FramebufferUpdateRequest     | (this document)       |
     | 4      | KeyEvent                     | (this document)       |
     | 5      | PointerEvent                 | (this document)       |
     | 6      | ClientCutText                | (this document)       |
     | 127    | VMWare                       | (historic assignment) |
     | 128    | Nokia Terminal Mode Spec     | (historic assignment) |
     | 249    | OLIVE Call Control           | (historic assignment) |
     | 250    | Colin Dean xvp               | (historic assignment) |
     | 251    | Pierre Ossman SetDesktopSize | (historic assignment) |
     | 252    | tight                        | (historic assignment) |
     | 253    | gii                          | (historic assignment) |
     | 254    | VMWare                       | (historic assignment) |
     | 255    | Anthony Liguori              | (historic assignment) |
     +--------+------------------------------+-----------------------+
        
     +--------+------------------------------+-----------------------+
     | Number | Name                         | References            |
     +--------+------------------------------+-----------------------+
     | 0      | SetPixelFormat               | (this document)       |
     | 2      | SetEncodings                 | (this document)       |
     | 3      | FramebufferUpdateRequest     | (this document)       |
     | 4      | KeyEvent                     | (this document)       |
     | 5      | PointerEvent                 | (this document)       |
     | 6      | ClientCutText                | (this document)       |
     | 127    | VMWare                       | (historic assignment) |
     | 128    | Nokia Terminal Mode Spec     | (historic assignment) |
     | 249    | OLIVE Call Control           | (historic assignment) |
     | 250    | Colin Dean xvp               | (historic assignment) |
     | 251    | Pierre Ossman SetDesktopSize | (historic assignment) |
     | 252    | tight                        | (historic assignment) |
     | 253    | gii                          | (historic assignment) |
     | 254    | VMWare                       | (historic assignment) |
     | 255    | Anthony Liguori              | (historic assignment) |
     +--------+------------------------------+-----------------------+
        
8.3. Server-to-Client Message Types
8.3. 服务器到客户端消息类型
8.3.1. Registry Name
8.3.1. 注册表名

The name of this registry is "Remote Framebuffer Server-to-Client Message Types".

此注册表的名称为“远程帧缓冲服务器到客户端消息类型”。

8.3.2. Registry Contents
8.3.2. 注册表内容

IANA established a registry for server-to-client message types that are used with the RFB protocol.

IANA为RFB协议使用的服务器到客户端消息类型建立了注册表。

The initial entries in the registry are:

注册表中的初始条目为:

       +--------+--------------------------+-----------------------+
       | Number | Name                     | References            |
       +--------+--------------------------+-----------------------+
       | 0      | FramebufferUpdate        | (this document)       |
       | 1      | SetColourMapEntries      | (this document)       |
       | 2      | Bell                     | (this document)       |
       | 3      | ServerCutText            | (this document)       |
       | 127    | VMWare                   | (historic assignment) |
       | 128    | Nokia Terminal Mode Spec | (historic assignment) |
       | 249    | OLIVE Call Control       | (historic assignment) |
       | 250    | Colin Dean xvp           | (historic assignment) |
       | 252    | tight                    | (historic assignment) |
       | 253    | gii                      | (historic assignment) |
       | 254    | VMWare                   | (historic assignment) |
       | 255    | Anthony Liguori          | (historic assignment) |
       +--------+--------------------------+-----------------------+
        
       +--------+--------------------------+-----------------------+
       | Number | Name                     | References            |
       +--------+--------------------------+-----------------------+
       | 0      | FramebufferUpdate        | (this document)       |
       | 1      | SetColourMapEntries      | (this document)       |
       | 2      | Bell                     | (this document)       |
       | 3      | ServerCutText            | (this document)       |
       | 127    | VMWare                   | (historic assignment) |
       | 128    | Nokia Terminal Mode Spec | (historic assignment) |
       | 249    | OLIVE Call Control       | (historic assignment) |
       | 250    | Colin Dean xvp           | (historic assignment) |
       | 252    | tight                    | (historic assignment) |
       | 253    | gii                      | (historic assignment) |
       | 254    | VMWare                   | (historic assignment) |
       | 255    | Anthony Liguori          | (historic assignment) |
       +--------+--------------------------+-----------------------+
        
8.4. RFB Encoding Types
8.4. RFB编码类型
8.4.1. Registry Name
8.4.1. 注册表名

The name of this registry is "Remote Framebuffer Encoding Types".

此注册表的名称为“远程帧缓冲区编码类型”。

8.4.2. Registry Contents
8.4.2. 注册表内容

IANA established a registry for encoding types that are used with the RFB protocol.

IANA为RFB协议使用的编码类型建立了一个注册表。

The initial entries in the registry are:

注册表中的初始条目为:

   +-------------------+----------------------------+------------------+
   | Number            | Name                       | References       |
   +-------------------+----------------------------+------------------+
   | 0                 | Raw                        | (this document)  |
   | 1                 | CopyRect                   | (this document)  |
   | 2                 | RRE                        | (this document)  |
   | 5                 | Hextile                    | (this document)  |
   | 16                | ZRLE                       | (this document)  |
   | -239              | Cursor pseudo-encoding     | (this document)  |
   | -223              | DesktopSize                | (this document)  |
   |                   | pseudo-encoding            |                  |
   | 4                 | CoRRE                      | (historic        |
   |                   |                            | assignment)      |
   | 6                 | zlib                       | (historic        |
   |                   |                            | assignment)      |
   | 7                 | tight                      | (historic        |
   |                   |                            | assignment)      |
   | 8                 | zlibhex                    | (historic        |
   |                   |                            | assignment)      |
   | 15                | TRLE                       | (this document)  |
   | 17                | Hitachi ZYWRLE             | (historic        |
   |                   |                            | assignment)      |
   | 1024 to 1099      | RealVNC                    | (historic        |
   |                   |                            | assignment)      |
   | -1 to -222        | tight options              | (historic        |
   |                   |                            | assignment)      |
   | -224 to -238      | tight options              | (historic        |
   |                   |                            | assignment)      |
   | -240 to -256      | tight options              | (historic        |
   |                   |                            | assignment)      |
   | -257 to -272      | Anthony Liguori            | (historic        |
   |                   |                            | assignment)      |
   | -273 to -304      | VMWare                     | (historic        |
   |                   |                            | assignment)      |
   | -305              | gii                        | (historic        |
   |                   |                            | assignment)      |
   | -306              | popa                       | (historic        |
   |                   |                            | assignment)      |
   | -307              | Peter Astrand DesktopName  | (historic        |
   |                   |                            | assignment)      |
   | -308              | Pierre Ossman              | (historic        |
   |                   | ExtendedDesktopSize        | assignment)      |
   | -309              | Colin Dean xvp             | (historic        |
   |                   |                            | assignment)      |
   | -310              | OLIVE Call Control         | (historic        |
   |                   |                            | assignment)      |
   | -412 to -512      | TurboVNC fine-grained      | (historic        |
   |                   | quality level              | assignment)      |
        
   +-------------------+----------------------------+------------------+
   | Number            | Name                       | References       |
   +-------------------+----------------------------+------------------+
   | 0                 | Raw                        | (this document)  |
   | 1                 | CopyRect                   | (this document)  |
   | 2                 | RRE                        | (this document)  |
   | 5                 | Hextile                    | (this document)  |
   | 16                | ZRLE                       | (this document)  |
   | -239              | Cursor pseudo-encoding     | (this document)  |
   | -223              | DesktopSize                | (this document)  |
   |                   | pseudo-encoding            |                  |
   | 4                 | CoRRE                      | (historic        |
   |                   |                            | assignment)      |
   | 6                 | zlib                       | (historic        |
   |                   |                            | assignment)      |
   | 7                 | tight                      | (historic        |
   |                   |                            | assignment)      |
   | 8                 | zlibhex                    | (historic        |
   |                   |                            | assignment)      |
   | 15                | TRLE                       | (this document)  |
   | 17                | Hitachi ZYWRLE             | (historic        |
   |                   |                            | assignment)      |
   | 1024 to 1099      | RealVNC                    | (historic        |
   |                   |                            | assignment)      |
   | -1 to -222        | tight options              | (historic        |
   |                   |                            | assignment)      |
   | -224 to -238      | tight options              | (historic        |
   |                   |                            | assignment)      |
   | -240 to -256      | tight options              | (historic        |
   |                   |                            | assignment)      |
   | -257 to -272      | Anthony Liguori            | (historic        |
   |                   |                            | assignment)      |
   | -273 to -304      | VMWare                     | (historic        |
   |                   |                            | assignment)      |
   | -305              | gii                        | (historic        |
   |                   |                            | assignment)      |
   | -306              | popa                       | (historic        |
   |                   |                            | assignment)      |
   | -307              | Peter Astrand DesktopName  | (historic        |
   |                   |                            | assignment)      |
   | -308              | Pierre Ossman              | (historic        |
   |                   | ExtendedDesktopSize        | assignment)      |
   | -309              | Colin Dean xvp             | (historic        |
   |                   |                            | assignment)      |
   | -310              | OLIVE Call Control         | (historic        |
   |                   |                            | assignment)      |
   | -412 to -512      | TurboVNC fine-grained      | (historic        |
   |                   | quality level              | assignment)      |
        
   | -523 to -524      | Nokia Terminal Mode Spec   | (historic        |
   |                   |                            | assignment)      |
   | -763 to -768      | TurboVNC subsampling level | (historic        |
   |                   |                            | assignment)      |
   | 0x574d5600 to     | VMWare                     | (historic        |
   | 0x574d56ff        |                            | assignment)      |
   +-------------------+----------------------------+------------------+
        
   | -523 to -524      | Nokia Terminal Mode Spec   | (historic        |
   |                   |                            | assignment)      |
   | -763 to -768      | TurboVNC subsampling level | (historic        |
   |                   |                            | assignment)      |
   | 0x574d5600 to     | VMWare                     | (historic        |
   | 0x574d56ff        |                            | assignment)      |
   +-------------------+----------------------------+------------------+
        
9. Security
9. 安全

The RFB protocol as defined here provides no security beyond the optional and cryptographically weak password check described in Section 7.2.2. In particular, it provides no protection against observation of or tampering with the data stream. It has typically been used on secure physical or virtual networks.

此处定义的RFB协议除了第7.2.2节中描述的可选和加密弱密码检查之外,不提供任何安全性。特别是,它不提供防止观察或篡改数据流的保护。它通常用于安全的物理或虚拟网络。

Security methods beyond those described here may be used to protect the integrity of the data. The client and server might agree to use an extended security type to encrypt the session, or the session might be transmitted over a secure channel such as IPsec [RFC4301] or SSH [RFC4254].

可使用此处所述之外的安全方法来保护数据的完整性。客户端和服务器可能同意使用扩展安全类型来加密会话,或者会话可能通过安全通道(如IPsec[RFC4301]或SSH[RFC4254])传输。

10. Acknowledgements
10. 致谢

James Weatherall, Andy Harter, and Ken Wood also contributed to the design of the RFB protocol.

James Weatherall、Andy Harter和Ken Wood也对RFB协议的设计做出了贡献。

RFB and VNC are registered trademarks of RealVNC Ltd. in the U.S. and in other countries.

RFB和VNC是RealVNC Ltd.在美国和其他国家/地区的注册商标。

11. References
11. 工具书类
11.1. Normative References
11.1. 规范性引用文件

[RFC1950] Deutsch, L. and J-L. Gailly, "ZLIB Compressed Data Format Specification version 3.3", RFC 1950, May 1996.

[RFC1950]Deutsch,L.和J-L.Gailly,“ZLIB压缩数据格式规范3.3版”,RFC 1950,1996年5月。

[RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification version 1.3", RFC 1951, May 1996.

[RFC1951]Deutsch,P.,“DEFLATE压缩数据格式规范1.3版”,RFC1951,1996年5月。

[XLIBREF] Nye, A., "XLIB Reference Manual R5", June 1994.

[XLIBREF]Nye,A.,“XLIB参考手册R5”,1994年6月。

11.2. Informative References
11.2. 资料性引用

[RFC4254] Ylonen, T. and C. Lonvick, "The Secure Shell (SSH) Connection Protocol", RFC 4254, January 2006.

[RFC4254]Ylonen,T.和C.Lonvick,“安全外壳(SSH)连接协议”,RFC 42542006年1月。

[RFC4301] Kent, S. and K. Seo, "Security Architecture for the Internet Protocol", RFC 4301, December 2005.

[RFC4301]Kent,S.和K.Seo,“互联网协议的安全架构”,RFC 43012005年12月。

[RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, May 2008.

[RFC5226]Narten,T.和H.Alvestrand,“在RFCs中编写IANA注意事项部分的指南”,BCP 26,RFC 5226,2008年5月。

Appendix A. Differences in Earlier Protocol Versions
附录A.早期协议版本的差异

For maximum interoperability, clients and servers should be prepared to fall back to the earlier 3.3 and 3.7 versions of the RFB protocol. Any version reported other than 3.7 or 3.8 should be treated as 3.3.

为了实现最大的互操作性,客户端和服务器应该准备好退回到RFB协议的早期3.3和3.7版本。报告的除3.7或3.8以外的任何版本应视为3.3。

All of the differences occur in the initial handshake phase. Once the session reaches the ClientInit and ServerInit messages, all three protocol versions are identical. Even within a protocol version, clients and servers may support different subsets of the encoding and pseudo-encoding types.

所有这些差异都发生在初始握手阶段。一旦会话到达ClientInit和ServerInit消息,所有三个协议版本都是相同的。即使在协议版本中,客户端和服务器也可能支持编码和伪编码类型的不同子集。

A.1. Differences in the Version 3.3 Protocol
A.1. 版本3.3协议中的差异

The ProtocolVersion message is:

ProtocolVersion消息是:

RFB 003.003\n (hex 52 46 42 20 30 30 33 2e 30 30 33 0a)

RFB 003.003\n(十六进制52 46 42 20 30 33 2e 30 33 0a)

In the security handshake (Section 7.1.2), rather than a two-way negotiation, the server decides the security type and sends a single word:

在安全握手(第7.1.2节)中,服务器决定安全类型并发送一个单词,而不是双向协商:

              +--------------+--------------+---------------+
              | No. of bytes | Type [Value] | Description   |
              +--------------+--------------+---------------+
              | 4            | U32          | security-type |
              +--------------+--------------+---------------+
        
              +--------------+--------------+---------------+
              | No. of bytes | Type [Value] | Description   |
              +--------------+--------------+---------------+
              | 4            | U32          | security-type |
              +--------------+--------------+---------------+
        

The security-type may only take the value 0, 1, or 2. A value of 0 means that the connection has failed and is followed by a string giving the reason, as described in Section 7.1.2.

安全类型只能采用值0、1或2。如第7.1.2节所述,值为0表示连接失败,后面是给出原因的字符串。

If the security-type is 1, for no authentication, the server does not send the SecurityResult message but proceeds directly to the initialization messages (Section 7.3).

如果安全类型为1,则对于无身份验证,服务器不发送SecurityResult消息,而是直接进入初始化消息(第7.3节)。

In VNC Authentication (Section 7.2.2), if the authentication fails, the server sends the SecurityResult message, but does not send an error message before closing the connection.

在VNC身份验证(第7.2.2节)中,如果身份验证失败,服务器将发送SecurityResult消息,但不会在关闭连接之前发送错误消息。

A.2. Differences in the Version 3.7 Protocol
A.2. 版本3.7协议中的差异

The ProtocolVersion message is:

ProtocolVersion消息是:

RFB 003.007\n (hex 52 46 42 20 30 30 33 2e 30 30 37 0a)

RFB 003.007\n(十六进制52 46 42 20 30 33 2e 30 37 0a)

After the security handshake, if the security-type is 1, for no authentication, the server does not send the SecurityResult message but proceeds directly to the initialization messages (Section 7.3).

安全握手后,如果安全类型为1,则对于无身份验证,服务器不发送SecurityResult消息,而是直接进入初始化消息(第7.3节)。

In VNC Authentication (Section 7.2.2), if the authentication fails, the server sends the SecurityResult message, but does not send an error message before closing the connection.

在VNC身份验证(第7.2.2节)中,如果身份验证失败,服务器将发送SecurityResult消息,但不会在关闭连接之前发送错误消息。

Authors' Addresses

作者地址

Tristan Richardson RealVNC Ltd. Betjeman House, 104 Hills Road Cambridge CB2 1LQ UK

Tristan Richardson RealVNC Ltd.英国剑桥希尔斯路104号Betjeman大厦CB2 1LQ

   Phone: +44 1223 310400
   EMail: standards@realvnc.com
   URI:   http://www.realvnc.com
        
   Phone: +44 1223 310400
   EMail: standards@realvnc.com
   URI:   http://www.realvnc.com
        

John Levine RealVNC Ltd.

约翰·莱文房地产有限公司。

   Phone: +44 1223 790005
   EMail: standards@taugh.com
   URI:   http://jl.ly
        
   Phone: +44 1223 790005
   EMail: standards@taugh.com
   URI:   http://jl.ly