vnc-client
is an original, pure-Java implementation of a VNC client, written from scratch.
It is an alternative to a few Java VNC viewers (TightVNC, TigerVNC, etc.) as they are all just copies of the Java viewer shipped with RealVNC.
pro:
- designed to use as a library in your own Java application
- complete support for zlib and Tight encodings used by the widely-spread TightVNC server
- ability to view several remote framebuffers at once
- thumbnail views
- readable Java source not based on the C source of the VNC viewer
contra:
- no support for a few RFB protocol features, such as
- clipboard support
- ZRLE encoding
- framebuffer size changing
- not completely tested (RRE, Hextile and TRLE encodings, for example)
Mandatory
- Java 8 minimum
Optional
- if JDK version is 11 or newer: JavaFX framework (probably OpenJFX) for JavaFX support
Settings are populated using Java Preferences. The settings are located in the system node of the preferences hierarchy, in ru/dmerkushov/vnc/client
.
LOGGING_LEVEL
- logging level. May beALL
(log everything),OFF
(log nothing), or one of level names:SEVERE
,WARNING
,INFO
,CONFIG
,FINE
,FINER
,FINEST
. Default isALL
JPEG_QUALITY
- JPEG quality when using Tight framebuffer encoding. May beHIGH
,MEDIUM
,LOW
, orNOJPEG
(don't use JPEG compression with Tight encoding). Default isNOJPEG
.FRAMEBUFFER_UPDATE_DELAY
- delay between framebuffer update requests, in milliseconds. Default is 100.FULL_UPDATE_COUNTER
- as soon as the counter of framebuffer update requests reaches this value, it is reset and a full framebuffer update request is issued. Default is 256.MOUSEMOVE_SEND_DELAY
- delay between mouse position notifications, in milliseconds. Default is 100.
Logging is done using the java.util.logging
framework. The logger is named "ru.dmerkushov.vnc.client.VncCommon
"
Setting the logging level is described in the Settings section.
Dmitriy Merkushov
Moscow, Russia
[email protected]
http://dmerkushov.ru
GitHub repository for the project: https://github.com/dmerkushov/vnc-client
VNC communication is based on the RFB (Remote FrameBuffer) protocol, described in RFC 6143, issued in March 2011. An extended variant of RFB is described in a non-standard spec called rfbproto available on GitHub.
Copies of both the RFC 6143 and the rfbproto spec (as of December 14, 2016) are present in this repository.
Basically. one should implement a password supplier, and then use one or more of the components to connect to the VNC server.
Then, a VNC (RFB) session must be initialized, and a password supplier must be set for the session. As a part of the session startup routine, the password supplier will be invoked.
Finally, a Swing or JavaFX component must be linked to the session, and the session may be started.
One should implement the PasswordSupplier
interface, which has the only method getPassword()
.
The method returns a String
and may throw an RfbOperationException
.
The trivial realization of a password supplier is provided: UiPasswordSupplier
uses a Swing dialog to ask for the password.
public static void main (String[] args) {
String host = JOptionPane.showInputDialog ("Host", "localhost");
int port = Integer.parseInt (JOptionPane.showInputDialog ("Port", "5901"));
JFrame frame = new JFrame ();
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.setSize (new java.awt.Dimension (500, 500));
RfbClientSession session = new RfbClientSession (Main.host, Main.port);
session.setPasswordSupplier (new UiPasswordSupplier ());
VncView vncView = new DefaultSwingVncView ();
vncView.setSession (session);
frame.add (vncView.getSwingComponent ());
session.startSession ();
frame.setVisible (true);
vncView.repaint ();
}
public void start (Stage primaryStage) {
String host = JOptionPane.showInputDialog ("Host", "localhost");
int port = Integer.parseInt (JOptionPane.showInputDialog ("Port", "5901"));
final RfbClientSession session;
try {
session = new RfbClientSession (host, port);
} catch (java.io.IOException ex) {
Logger.getLogger (Main.class.getName ()).log (Level.SEVERE, null, ex);
return;
}
session.setPasswordSupplier (new UiPasswordSupplier ());
VncView vncView = new DefaultJavaFxVncView ();
vncView.setSession (session);
try {
session.startSession ();
} catch (RfbSessionException | java.io.IOException ex) {
Logger.getLogger (Main.class.getName ()).log (Level.SEVERE, null, ex);
}
HBox root = new HBox ();
root.getChildren ().add (vncView.getJavafxNode ());
primaryStage.setScene (new Scene (root, 1200, 800));
primaryStage.setOnHiding (event -> Platform.runLater (() -> {
try {
session.setSessionState (RfbSessionState.Finished);
} catch (RfbSessionException ex) {
Logger.getLogger (Main.class.getName ()).log (Level.SEVERE, null, ex);
}
}));
primaryStage.show ();
}
A VNC session is broken into three main stages:
- Handshake
- Initialization
- Normal (regular) operation
First, a TCP connection is established by the client. Then, the handshake stage of the session is started.
Handshake stage includes:
- adjustment of the RFB protocol version (protocol version handshake)
- testing the client's authenticity (security handshake)
If the handshake is passed successfully, the routine continues with the initialization stage.
Initialization stage includes:
- the client informs the server if the session should be shared among several clients
- the server informs the client of the preferred pixel representation and the session identification
After that, goes the normal (regular) operation. The client sends framebuffer update requests, pointer and keyboard events. The server sends framebuffer updates. Other supplementary messages are probable, too:
- by the client
- set pixel format
- set available framebuffer representation formats (set encodings) and/or inform of the supported RFB extensions, using the so-called pseudo encodings
- set text in the clibboard (client cut text)
- other messages not described in RFC 6143, but approved by the client and the server, according to the supported RFB extensions
- by the server
- beep (bell)
- set colormap entries
- set text in the clipboard (server cut text)
- other messages not described in RFC 6143, but approved by the client and the server, according to the supported RFB extensions
Approval of the supported RFB extensions on the client side is usually reached by the set encodings message including one or more pseudo encodings. Agreement of the supported RFB extensions on the server side is usually reached by sending framebuffer update messages using these pseudo encodings. But anyway, the approval procedure depends on the extension specification.
According to RFC 6143, the following framebuffer encodings are allowed:
- Raw - a direct representation of a framebuffer as a rectangular array of pixels (MUST be supported by every VNC client and every VNC server)
- CopyRect - copying of a previously-sent rectangle to another location
- RRE - a group of rectangles of the same color and differrent sizes
- Hextile - a variadic encoding of tiles sized 16x16 pixels
- TRLE - another variadic encoding, more effective than Hextile
- ZRLE - Zlib-compressed TRLE
rfbproto adds the following encodings:
- CoRRE
- zlib
- Tight
- zlibhex
Bold in these two lists are the encodings that are supported AND tested with this vnc-client.
Actually, there are much more framebuffer encodings than described in RFC 6143 and rfbproto, many of them proprietary.
vnc-client is licensed with GNU General Public License 2. A copy of the license is supplied within the repository.
Though the author's favorite is the Apache License, two of the project's classes (ru.dmerkushov.vnc.client.ui.events.Keysyms
и ru.dmerkushov.vnc.client.rfb.messages.handshake.SecurityHandshake4_VNCauth_C2S.DesCipher
) are based on classes of the TigerVNC Java viewer that is licensed with GPLv2. Hence, this work may be seen as a derived work in GPL terms.
Source java packages:
ru.dmerkushov.vnc.client
- base package, contains classes:Main
(a usage sample),VncCommon
(common routines),VncException
(base class for the client's exceptions)rfb
- RFB protocol realizationdata
- basic RFB data:RfbColorMap
(palette),RfbPixelFormat
(format for the pixel representation),RfbRectangle
(framebuffer rectangle)pixeldata
- graphic data representations (encodings)
messages
- RFB messages, broken by RFB connection stages:handshake
,initialization
,normal
operation
- realizations of RFB connection stagessession
- client-side representation of an RFB session (RfbClientSession
) and utility classes for itpassword
-PasswordSupplier
interface and its default implementation,UiPasswordSupplier
ui
- GUI classes:VncView
- an interface that must be implemented to connect a view component to a client sessionDefaultJavaFxVncView
- default implementation ofVncView
, JavaFX-styleDefaultSwingVncView
- default implementation ofVncView
, Swing-styleThumbnailJavaFxVncView
- auto-resizing implementation ofVncView
(for the purpose of thumbnail view of the remote framebuffer), JavaFX-styleThumbnailSwingVncView
- auto-resizing implementation ofVncView
(for the purpose of thumbnail view of the remote framebuffer), Swing-styleevents
- events to send to the VNC server