Loading learning content...
VNC (Virtual Network Computing) represents a fundamentally different philosophy from RDP's Windows-centric approach. Developed at AT&T's Cambridge Research Laboratory in the late 1990s, VNC was designed around a single, powerful principle: the remote framebuffer should be accessible from anywhere, to any system, using any platform.
This philosophy led to the Remote Framebuffer (RFB) protocol—an elegantly simple specification that treats the remote desktop as a rectangular array of pixels. The server continuously updates this framebuffer as the desktop changes; the client displays it and sends input events back. This conceptual simplicity enables remarkable interoperability: a VNC client on macOS can control a Windows server, a Linux thin client can access a Raspberry Pi, and embedded devices can provide remote interfaces on any browser.
VNC's openness has spawned a diverse ecosystem of implementations. Unlike RDP, which is controlled by Microsoft, the RFB protocol specification has been publicly available since VNC's inception. This openness has produced dozens of VNC implementations—both commercial and open-source—each optimizing for different use cases while maintaining core interoperability.
Understanding VNC is essential for cross-platform remote access, embedded systems, Unix/Linux administration, and scenarios where platform flexibility outweighs the advanced features of proprietary alternatives.
By completing this page, you will master the RFB protocol specification, understand VNC's diverse encoding methods and their trade-offs, comprehend VNC security from password authentication to TLS encryption, and learn about major VNC implementations and their distinguishing features.
The Remote Framebuffer (RFB) protocol is the foundation of all VNC implementations. Understanding RFB is essential because its design decisions—both strengths and limitations—cascade through every VNC deployment.
Design Philosophy
RFB was designed with several key principles:
Thin Client: The client should be as simple as possible, requiring minimal processing power. This enables VNC viewers on constrained devices.
Stateless Updates: The server is responsible for managing state. If the client loses track of display state, the server can resend everything.
Display-Agnostic: The protocol knows nothing about windows, applications, or UI toolkits. It sees only pixels.
Encoding Flexibility: Multiple encoding methods allow optimization for different network conditions and content types.
Protocol Overview
RFB is a simple, message-based protocol running over TCP:
Connection Establishment
RFB connection proceeds through three phases:
Phase 1: Protocol Version Handshake
Both sides exchange protocol version strings:
RFB 003.008
The format is 'RFB xxx.yyy' where xxx.yyy is the version number. Common versions:
Phase 2: Security Negotiation
RFB 3.7+ servers send a list of supported security types:
| Type | Name | Description |
|---|---|---|
| 1 | None | No authentication |
| 2 | VNC Authentication | DES challenge-response |
| 5 | RA2 | RealVNC proprietary |
| 6 | RA2ne | RealVNC proprietary (no encryption) |
| 16 | Tight | TightVNC tunneling |
| 18 | TLS | Generic TLS wrapper |
| 19 | VeNCrypt | Extensible encrypted transport |
The client selects one security type, authentication proceeds, and the server reports success or failure.
Phase 3: Initialization
The client sends ClientInit containing a single byte 'shared' flag:
The server responds with ServerInit:
After initialization, the client may request a different pixel format via SetPixelFormat message. The server translates its native format to the client's request. This enables clients with limited color capability (8-bit displays) to connect to high-color servers, and conversely allows color reduction for bandwidth savings.
RFB defines a small set of message types, reflecting its minimalist design philosophy. Understanding these messages is key to analyzing VNC traffic and developing VNC-compatible software.
Client-to-Server Messages
The base protocol defines four client message types:
| Type | ID | Purpose |
|---|---|---|
| SetPixelFormat | 0 | Request specific pixel encoding |
| SetEncodings | 2 | Declare supported encoding types |
| FramebufferUpdateRequest | 3 | Request display update |
| KeyEvent | 4 | Keyboard key press/release |
| PointerEvent | 5 | Mouse movement and button state |
| ClientCutText | 6 | Clipboard text from client |
1. SetPixelFormat (Type 0)
Sent after initialization or when the client wants to change color depth:
Message-type (1 byte): 0
Padding (3 bytes)
Pixel-format (16 bytes): Detailed format specification
This allows bandwidth optimization—requesting 8-bit color instead of 32-bit reduces data by 4x.
2. SetEncodings (Type 2)
Declarates which encoding types the client supports, in preference order:
Message-type (1 byte): 2
Padding (1 byte)
Number-of-encodings (2 bytes)
Encoding-type[n] (4 bytes each): List of supported encodings
The server will use the first encoding from the client's list that it supports. This extensible mechanism allows new encodings without protocol version changes.
| ID | Name | Description | Best For |
|---|---|---|---|
| 0 | Raw | Uncompressed pixel data | LAN, debugging |
| 1 | CopyRect | Copy from another screen region | Window moves, scrolling |
| 2 | RRE | Rise-and-run-length encoding | Simple graphics |
| 4 | CoRRE | Compact RRE variant | Small rectangles |
| 5 | Hextile | Tile-based mixed encoding | General purpose |
| 6 | Zlib | Zlib-compressed raw | High-color, bandwidth limited |
| 7 | Tight | Advanced mixed compression | General purpose (TightVNC) |
| 16 | ZRLE | Zlib Run-Length Encoding | General purpose (standard) |
| -223 | DesktopSize | Pseudo-encoding: resize support | Resizable sessions |
| -232 | Cursor | Pseudo-encoding: local cursor | Cursor rendering |
| -239 | JPEG Quality | Pseudo-encoding: JPEG level | Quality control |
3. FramebufferUpdateRequest (Type 3)
The client requests a display update:
Message-type (1 byte): 3
Incremental (1 byte): 0=full update, 1=changes only
X-position (2 bytes): Starting X coordinate
Y-position (2 bytes): Starting Y coordinate
Width (2 bytes): Region width
Height (2 bytes): Region height
Incremental Updates: When incremental=1, the server sends only regions that have changed since the last update. This is the normal operating mode—the client continuously requests incremental updates, creating a polling loop.
Non-Incremental Updates: When incremental=0, the server sends the entire requested region regardless of changes. Used for initial display or recovering from errors.
4. KeyEvent (Type 4)
Keyboard input:
Message-type (1 byte): 4
Down-flag (1 byte): 1=pressed, 0=released
Padding (2 bytes)
Key (4 bytes): X11 keysym value
VNC uses X11 keysym values for key identification—a platform-neutral key encoding. This works well for standard keys but can be problematic for special keys, international layouts, and input methods.
5. PointerEvent (Type 5)
Mouse input:
Message-type (1 byte): 5
Button-mask (1 byte): Bit flags for each button (bit 0=left, 1=middle, 2=right, 3-7=extra)
X-position (2 bytes): Cursor X coordinate
Y-position (2 bytes): Cursor Y coordinate
Pointer events are absolute coordinates, not relative movements. This simplifies the protocol but requires coordinate translation when the client window is scaled.
6. ClientCutText (Type 6)
Clipboard transfer from client:
Message-type (1 byte): 6
Padding (3 bytes)
Length (4 bytes): Text length
Text (length bytes): Latin-1 encoded text
The original protocol specified Latin-1 (ISO 8859-1) encoding, which is problematic for international text. Extensions handle UTF-8 and other content types.
Server-to-Client Messages
The base protocol defines four server message types:
| Type | ID | Purpose |
|---|---|---|
| FramebufferUpdate | 0 | Display update (rectangles) |
| SetColourMapEntries | 1 | Color palette for indexed mode |
| Bell | 2 | Audio bell notification |
| ServerCutText | 3 | Clipboard text from server |
1. FramebufferUpdate (Type 0)
The primary display update message:
Message-type (1 byte): 0
Padding (1 byte)
Number-of-rectangles (2 bytes): Count of following rectangles
Rectangle[n]: Variable-size rectangle data
Each rectangle specifies:
Multiple rectangles in one update allow efficient batching of changes across the screen.
The Update Request/Response Loop
VNC's fundamental operation pattern:
This client-driven model gives the client control over update frequency and allows flow control—if the client is slow to render, it delays requesting the next update, naturally throttling the server.
2. Bell (Type 2)
Simple audio notification:
Message-type (1 byte): 2
No additional data—the client plays its default bell sound. Rudimentary audio support compared to RDP's full audio redirection.
3. ServerCutText (Type 3)
Clipboard transfer from server (same format as ClientCutText).
RFB uses 'pseudo-encodings' to negotiate capabilities without protocol changes. The client includes pseudo-encodings in SetEncodings to signal feature support. For example, including the Cursor pseudo-encoding (-239) tells the server the client supports local cursor rendering. The server then sends cursor shape data instead of drawing cursors in the framebuffer.
RFB's encoding flexibility is central to VNC's performance characteristics. Different encodings optimize for different scenarios—understanding their trade-offs is essential for tuning VNC deployments.
Raw Encoding (Type 0)
The simplest encoding: uncompressed pixel data in the specified pixel format.
Structure:
Use Case:
Bandwidth:
CopyRect Encoding (Type 1)
Copies pixels from another screen location—no pixel data transmitted.
Structure:
Source x-position (2 bytes)
Source y-position (2 bytes)
Use Case:
Bandwidth:
Tight Encoding (Type 7)
Developed by TightVNC, Tight encoding is one of the most sophisticated standard encodings, combining multiple compression strategies:
Components:
Basic Compression: Zlib compression of raw pixel data with optional filtering (palette conversion, gradient filter)
Gradient Filter: Predicts pixel values based on neighbors, encodes differences. Effective for photographs and gradients.
Palette Optimization: For regions with few colors, sends a color palette and indices. Very efficient for UI elements.
JPEG Compression: For photographic regions, uses JPEG encoding. Lossy but dramatically reduces size.
Subencoding Types in Tight:
Quality Control: Tight supports quality levels (-32 to -23 pseudo-encodings) that control JPEG quality. Lower quality = smaller size, more artifacts.
Tight's Adaptive Selection:
Tight analyzes each rectangle and selects the most appropriate method:
This content-aware selection makes Tight highly effective across diverse desktop content.
ZRLE Encoding (Type 16)
Zlib Run-Length Encoding became the standard encoding in RFB 3.8:
Structure:
Advantages:
| Encoding | Compression Ratio | CPU (Server) | CPU (Client) | Best Network |
|---|---|---|---|---|
| Raw | 1:1 | Minimal | Minimal | Gigabit LAN |
| CopyRect | N/A (4 bytes) | Low | Low | Any |
| Hextile | 2:1 to 10:1 | Low-Medium | Low | LAN/Fast WAN |
| ZRLE | 3:1 to 15:1 | Medium | Medium | WAN |
| Tight | 5:1 to 50:1 | Medium-High | Medium | Low bandwidth |
| Tight+JPEG | 20:1 to 100:1 | High | Medium | Very low bandwidth |
Some VNC implementations (notably TurboVNC, TigerVNC) have added H.264 encoding support. This isn't part of the official RFB specification but follows the extension mechanism. H.264 provides dramatic compression for video content and animations, leveraging hardware encoding/decoding when available.
VNC's original security was minimal—reflecting both its 1990s origins and its initial use in trusted network environments. Modern VNC deployments require careful attention to security, using protocol extensions and external mechanisms to protect remote access.
Original VNC Authentication (Type 2)
The base RFB security uses a simple challenge-response mechanism:
Critical Weaknesses:
VNC Authentication should never be used alone for internet-exposed access.
VeNCrypt (Type 19)
VeNCrypt, introduced by VeNCrypt project and adopted by TigerVNC and others, provides a flexible security framework:
VeNCrypt Structure:
VeNCrypt Subtypes:
| Subtype | TLS | Auth Method |
|---|---|---|
| Plain | No | Username/password |
| TLSNone | Yes | None (TLS only) |
| TLSVnc | Yes | VNC password |
| TLSPlain | Yes | Username/password |
| X509None | Yes | X.509 certificate only |
| X509Vnc | Yes | X.509 + VNC password |
| X509Plain | Yes | X.509 + username/password |
X.509 Certificate Authentication:
With X509 subtypes:
SSH Tunneling
The most common method for securing VNC over untrusted networks:
Client → SSH Server (encrypted) → VNC Server (localhost)
Setup:
ssh -L 5901:localhost:5900 user@serverAdvantages:
Disadvantages:
Exposing VNC directly to the internet, even with TLS, is risky. VNC has been targeted by ransomware operators who scan for exposed instances and brute-force passwords. Always use VPN, SSH tunneling, or place VNC behind a gateway with additional authentication. Monitor for unauthorized access attempts and consider fail2ban-style rate limiting.
View-Only and Access Control
Many VNC implementations support access restrictions:
View-Only Mode:
IP-Based Access Control:
Integration with System Authentication:
Advanced VNC implementations integrate with system authentication:
Clipboard Security:
Clipboard transfer can be a security concern:
The open nature of the RFB protocol has spawned a diverse ecosystem of VNC implementations. Each emphasizes different characteristics—understanding the major players helps in selecting the right tool for specific requirements.
TigerVNC
Forked from TightVNC in 2009, TigerVNC is the leading open-source VNC implementation for Linux environments.
Key Features:
Best For:
TightVNC
Originated the Tight encoding and was the primary open-source VNC for many years.
Key Features:
Status:
| Implementation | License | Platform Focus | Encoding | Security |
|---|---|---|---|---|
| TigerVNC | GPL | Linux primary | ZRLE, Tight | VeNCrypt, TLS |
| TightVNC 2 | Commercial | Windows | Tight | TLS optional |
| TurboVNC | GPL | High-performance | Tight, 3D | TLS, SASL |
| RealVNC | Commercial | Cross-platform | Proprietary | Cloud auth, AES-256 |
| UltraVNC | GPL | Windows | Ultra, Tight | MS-Logon, TLS |
| x11vnc | GPL | Unix existing display | Standard | SSH integration |
| noVNC | MPL | Browser (WebSocket) | Tight | HTTPS |
TurboVNC
Optimized for high-performance 3D and video workloads:
Key Features:
Use Cases:
RealVNC (VNC Connect)
Commercial implementation from the original VNC developers:
Key Features:
Editions:
UltraVNC
Windows-focused open-source implementation:
Key Features:
Best For:
noVNC
HTML5/WebSocket-based VNC client:
Key Features:
Architecture:
Use Cases:
For Linux administration: TigerVNC. For 3D/visualization: TurboVNC. For Windows support: UltraVNC. For zero-install web access: noVNC. For cross-platform enterprise with commercial support: RealVNC. The common RFB protocol ensures basic interoperability, but advanced features may require matching client and server implementations.
Understanding the fundamental differences between VNC and RDP helps in selecting the appropriate technology and optimizing deployments.
Philosophical Differences
VNC: Platform-Agnostic Simplicity
VNC treats the remote computer as a black box with a screen and input devices. The protocol knows nothing about the operating system, window manager, or applications. This abstraction provides:
RDP: Deep Integration
RDP is tightly coupled with Windows internals. It understands Windows graphics subsystems, authentication mechanisms, and system services. This integration enables:
Technical Comparison
Session Model:
Display Capture:
Input Handling:
Bandwidth Efficiency:
Connection Establishment:
When to Use Each:
| Scenario | Recommended |
|---|---|
| Remote Windows administration | RDP |
| Linux server access | VNC (or SSH for CLI) |
| macOS remote access | VNC (Apple Remote Desktop uses ARD/VNC) |
| Cross-platform support | VNC |
| Help desk seeing user's screen | VNC |
| Multi-user server sessions | RDP |
| Video editing/3D remotely | TurboVNC or RDP with RemoteFX |
| Embedded device access | VNC |
| Web-based console access | noVNC |
| Enterprise Windows deployment | RDP with RDS/AVD |
Modern environments often use both protocols. A typical enterprise might use RDP for Windows server access and AVD, while maintaining VNC for Linux systems, embedded devices, and troubleshooting scenarios where seeing the exact user experience matters. Many jump hosts and management consoles support both protocols.
We've conducted a comprehensive exploration of VNC and the RFB protocol, from its elegant simplicity to its diverse implementation ecosystem. Let's consolidate the essential knowledge.
Looking Forward
With comprehensive understanding of both RDP and VNC—the two dominant remote desktop protocols—we're prepared to examine the performance optimization techniques that maximize their effectiveness. The next page explores how network conditions, encoding choices, and client/server tuning affect the remote desktop experience, providing practical guidance for achieving responsive, efficient remote access.
You now possess deep knowledge of VNC and the RFB protocol—from message-level protocol details through encoding methods to the implementation ecosystem. This expertise enables you to deploy, configure, secure, and troubleshoot VNC across diverse platforms. Combined with your RDP knowledge, you can architect appropriate remote access solutions for any environment.