玩式草子─ソフトウェアとたわむれる日々

第60回いまさらながらVNC[その2]

前回ずいぶん遠回りしてしまったものの、なぜ手元の環境でVNCが必要となったのか、という話をしました。

VNCを使えば、隣りのマシンで動いているWindowsの画面をLinuxのデスクトップ中に表示することができ、KVMスイッチなどでキーボードや画面を切り替える必要もなく、キャプチャの開始や終了、ファイルの移動等の操作が可能になります。

図1 VNCの動作例
図1 VNCの動作例

この画面は、一見するとVirtualBox等の仮想環境でWindowsを動かしているのと変りなく見えます。しかし、ここで動いているキャプチャソフトはUSB外付けキャプチャボックスを操作しており、それを接続するために実際のWindowsマシン一式が必要となったわけです。

さて、それではVNCはどのようなしくみで異なる環境に画面を表示させているのでしょう? 今回はVNCのしくみや歴史について紹介してみます。

VNCとRFB

VNCはサーバ・クライアントタイプのソフトウェアで、画面を飛ばしたい環境(上記の例ではWindows)でサーバ(vncserver)を動かし、画面を受けとりたい環境(同Linux)でクライアント(vncviewer)を動かします。VNCのサーバとクライアントはRFB(Remote Frame Buffer)という通信プロトコルを使ってデータをやりとりします。

RFBプロトコルは、"Remote Freme Buffer"という名が示すように、⁠フレーム・バッファ」すなわち、画面データを直接やりとりするためのプロトコルです。

X Windows Systemのようにネットワーク透過に設計されたウィンドウシステムの場合、ネットワークに流れるのはX11プロトコル、すなわち画面をどのように描画するかを記述したデータになります。それに対し、RFBプロトコルでは、サーバが取得した画面データそのものがネットワーク経由でクライアントに送られます。すなわちVNCでは、サーバは常にスクリーンをキャプチャし続けてそのデータをクライアントに送り、クライアントは届いたキャプチャデータを使ってリモート環境の画面を表示しているわけです。

もちろん、キャプチャした画面データを全てそのままやりとりすると、データ量も膨大になって描画もスムーズにはいきません。そのためRFBプロトコルでは、画面を複数の領域に分割し、書き換えが必要な領域のデータのみを送ったり、データを圧縮してやりとりするような機能が定義されています。

一方、クライアントからサーバ側の環境を操作するために、クライアントが受けとったキーボードやマウスの入力をサーバ側に送信する機能もあります。RFBプロトコルでは、クライアントが受けとった入力はキーイベントポインタイベントとしてサーバに送られ、サーバはそれらをあたかも手元で生じたイベントのように加工してOSへ送り、要求された操作を実現します。

VNCの基盤となっているRFBプロトコルは、1998年に最初のバージョン(RFB 3.3)が一般公開され、その後、数回のバージョンアップを経て、現在は2005年に公開されたバージョン3.8が広く利用されています。また、2011年にはRFC6143としてIETFにも承認され、特定の企業や組織から離れて真に誰でも自由に使えるプロトコルとなりました。

VNCの歴史と各種実装

RFBプロトコルとそれを実装したVNCというソフトウェアは、イタリアの老舗事務機器メーカのオリベッティ(Olivetti)が英国ケンブリッジ大学に設置したORL(Olivetti Research Laboratory)で行なっていたthin-clientに関する研究の中から、1998年ごろに生まれました。

"thin-client"とは、画面表示とユーザからの入力を受けとる程度の機能しか持たない端末のことです。この種の端末は単体では使いものにならないものの、ネットワーク経由で専用のサーバと接続し、必要な処理はサーバ側で行なって、端末側はその結果を表示する作業に専念するという分業体制を取ることで、通常のPCと同等の作業をこなすことができます。かつてコンピュータがずいぶん高価だったころ、低機能ながら安価な"thin-client"は十分魅力的な選択肢でした。

"thin-client"の代表がX Windows System用のX端末です。X端末はX Windows Systemの画面描画機能のみを組み込んだ安価なコンピュータで、外部のホストで動作させたX用のアプリケーションの画面を表示することができます。

前述のように、X Windows Systemの場合、ネットワーク経由でやりとりするのは画面の描画手順を記述したX11プロトコルなので、X端末はXに対応したアプリケーションの画面しか表示できません。一方、90年代も後半になってくると、WindowsやMacOSなども広く使われるようになり、より汎用性が高い"thin-client"が求められるようになりました。そこで考案されたのが、描画された画面そのものを転送しようというRFBプロトコルのアイデアで、それを実装したソフトウェアとしてVNCが生まれました。

図2 VNCのロゴ
図2 VNCのロゴ

RFBプロトコルは、画面に出力された結果を転送するように設計されているので、XやWindows、MacOSといった設計が根本から異なるウィンドウシステム間でも動作可能です。そこでORLの開発者たちは、VNCをGPLに基づくフリーソフトウェアとして公開し、さらに多くのプラットフォームに対応させようとしました。

その後、ORLはAT&Tに買収され、しばらくは「AT&Tケンブリッジ研究所」として運営されたものの、AT&T自身が経営不振におちいった結果、2002年に閉鎖されてしまいました。そこでVNCの関係者たちは、VNCの開発を継続するために自らでRealVNCという会社を設立し、RFBプロトコルを実装した新しいソフトウェアを社名と同じ"RealVNC"という名称で開発、販売することにしました。

図3 RealVNCのロゴ
図3 RealVNCのロゴ

"RealVNC"は、"VNC"の元々の開発者たちが作った正統な後継ソフトウェアではあるものの、商用ソフトウェアとして開発されているため、かってのようにソースコードは公開されず、機能が限られたトライアル版のみ無料でダウンロードできるようになっています。

一方、もともとのVNCのソースコードはGPLに基づいて公開されていたため、それを元にした派生ソフトウェアも開発されていきました。それら派生ソフトウェアは、もともとのVNCのソースコードを利用しつつ、RFBプロトコルの新バージョンに対応したり、転送するデータを効率よく圧縮したり、OpenGLの機能を利用して描画の高速化を図るなど、オリジナルには無い便利な機能が追加されています。以下、現在も開発が続いている主要なVNCソフトウェアを紹介しましょう。

TightVNC

画像

TightVNCはオリジナルのVNCにtight encodeと呼ばれる、JPEGとzlibを用いたデータ圧縮機能を追加した派生バージョンです。"tight encode"を使えば、サーバからクライアントに送るデータ量を大幅に削減でき、ネットワークの負荷は減る反面、データの圧縮、展開にかかるCPUの負荷は増えます。

TigerVNC

画像

TightVNCを元に、OpenGLの機能も利用して画面描画を高速化した派生バージョンです。OpenGLを利用するためにFLTK(Fast, Light ToolKit)というGUIライブラリを利用しているので、TigerVNCを使う際には事前にFLTKをインストールしておく必要があります。

TurboVNC

画像

TightVNCとTigerVNCを元に、3D機能や動画処理に便利な機能を追加した派生バージョンです。TigerVNCの開発者のうち、3D機能や動画処理の強化に関心を持つ人々が、それらをあまり重視しないTigerVNCの開発方針に反発して立ちあげたプロジェクトです。TurboVNCでは、最近のCPUが持つ並列化機能(SIMD機能)を積極的に利用しているJpeg-turboライブラリを採用して、データの圧縮、展開の高速化を目指しています。

UltraVNC

画像

元々のVNCが持っていたマルチプラットフォーム性を廃して、Windows用に特化することで性能や信頼性を高めることを目指した派生バージョンです。UltraVNC自身はWindows以外の環境では動作しないものの、Linuxで動いているVNCクライアントからUltraVNCサーバに接続したり、UltraVNCのクライアントからLinuxのVNCサーバに接続することは問題ありません。

gtk-VNC

GNOME系のデスクトップ環境が利用しているGTKツールキット向けに開発されたVNC用ウィジェットです。VNC(RFBプロトコル)の機能をGTKツールキットの一部として利用できるので、RFBプロトコルに対応したソフトウェアを簡単に作成できるものの、対応する機能的には上記専用のソフトウェアに比べるとやや見劣りがするようです。

LibVNCServer/LibVNCClient

VNCのサーバ/クライアントの機能をそれぞれライブラリとして実装したソフトウェアです。gtk-VNC同様、専用のVNCソフトウェアに比べると機能的には後追いの感があるものの、必要な機能をライブラリとして容易に利用できるため、KDE用のリモートデスクトップクライアントKRDCやVirtualBoxの組み込みVNCサーバ機能などがこのライブラリを利用しています。

VNCのインストール

前節で紹介した各種VNCソフトウェアを検討した結果、Linuxで使うVNCクライアントはTigerVNCWindowsで使うVNCサーバはUltraVNCを使うことにしました。

前節で紹介したように、TigerVNCはFLTKツールキットを必要とするので、まずFLTKツールキットをインストールしておきます。

$ wget http://fltk.org/pub/fltk/1.3.2/fltk-1.3.2-source.tar.gz
$ tar xvf fltk-1.3.2-source.tar.gz
$ cd fltk-1.3.2
$ ./configure --enable-shared
checking for gcc... gcc
...
$ make
=== making src ===
g++ -L. -Wl,-soname,libfltk.so.1.3 -lXext -lXft -lfontconfig -lXinerama -lpthread -ldl -lm -lX11 -shared -fPIC -o libfltk.so.1.3 ...
 ...
$ sudo make install
mkdir -p /usr/local/bin
rm -f /usr/local/bin/fltk-config
/usr/bin/install -c -m 755 fltk-config /usr/local/bin
 ...

次にTigerVNCのソースコードをダウンロードし、展開します。

$ wget https://github.com/TigerVNC/tigervnc/archive/v1.3.1.tar.gz
$ tar xvf v1.3.1.tar.gz
$ cd tigervnc-1.3.1

TigerVNCはビルドシステムにcmakeを使っているので、cmakeの流儀にしたがって、作業用のディレクトリを作ってビルド、インストールします。

$ mkdir build ; cd build
$ cmake -G'Unix Makefiles' ..
-- The C compiler identification is GNU 4.6.3
-- The CXX compiler identification is GNU 4.6.3
 ...
$ make
Scanning dependencies of target os
[  1%] Building C object common/os/CMakeFiles/os.dir/print.c.o
[  1%] Building C object common/os/CMakeFiles/os.dir/net.c.o
...
$ sudo make install
/usr/bin/cmake -H/mnt/Srcs/T/TigerVNC/tigervnc-1.3.1 -B/mnt/Srcs/T/TigerVNC/tigervnc-1.3.1/build --check-build-system CMakeFiles/Makefile.cmake 0
 ...

Windows用のUltraVNCは、UltraVNCの公式サイトから最新の1.1.9.6をダウンロードしてきました。こちらはSetup機能付きなので、そのままセットアップしていきます。

図4 UltraVNCのSetupウィザード
図4 UltraVNCのSetupウィザード

特に凝ったことをするつもりはないので、たいていの設定はデフォルトままですが、起動直後からVNCを使えるようにするため、Windowsのシステムサービスとして起動するオプションは指定しておきました。

図5 UltraVNCをWindowsのシステムサービスに追加
図5 UltraVNCをWindowsのシステムサービスに追加

インストールが終われば、システムトレイにUltraVNCのアイコンが現われるので、メニューから"Admin Property"を選び、VNC接続用のパスワードを指定しておきます。

図6 接続用のパスワードを設定
図6 接続用のパスワードを設定

サーバ側の準備ができれば、Linux側からvncviewerを起動して接続します。

$ vncviewer 192.168.1.11

TigerVNC Viewer 32-bit v1.3.1 (20140622)
Built on Jun 22 2014 at 15:55:13
Copyright (C) 1999-2011 TigerVNC Team and many others (see README.txt)
See http://www.tigervnc.org for information on TigerVNC.

Tue Jul 29 17:38:33 2014
 CConn:       connected to host 192.168.1.11 port 5900
 CConnection: Server supports RFB protocol version 3.8
 CConnection: Using RFB protocol version 3.8

Tue Jul 29 17:38:37 2014
 PlatformPixelBuffer: Using default colormap and visual, TrueColor, depth 24.
 CConn:       Using pixel format depth 24 (32bpp) little-endian rgb888
 CConn:       Using Tight encoding

 ...
図7 TigerVNCからUltraVNCに接続した画面
図7 TigerVNCからUltraVNCに接続した画面

起動時のメッセージが示すように、VNCのサーバとクライアントは双方が利用可能な機能についてやりとりし、使用するRFBプロトコルのバージョンやデータの圧縮方法を決定します。今回は、サーバ側は64ビット版Windows7上のUltraVNC-1.1.9.6、クライアント側は32ビット版TigerVNC-1.3.1という組合せにしてみました。サーバとクライアントの間で、CPUアーキテクチャやVNCの実装が異なっていても、特に問題なくRFBプロトコルのバージョン(3.8)やデータの圧縮方法(Tight encoding)が決まりました。


多少なりともコンピュータに詳しい人間からすると、あるマシンが表示している画面そのものをキャプチャして別のマシンで表示させる、というVNCのアイデアは、強引かつ無駄が多すぎるように感じます。

事実、VNCが生まれた当時のCPUやビデオカード、ネットワークは、VNCを使うには力不足で、当時試した際には、画面の書き変わる様が見てとれるくらい動作が遅かった記憶があります。

しかしながら、CPUやビデオカードの性能が格段に向上し、ネットワークもギガビット・スイッチが数千円で買える時代になってくると、VNC経由で動画ファイルを操作することも不可能ではなくなりました。

筆者の場合、Linuxがメインの環境なので、Linuxでは使えない周辺機器は、便利そうでも敬遠しがちになります。しかし、VNCを使えばWindows環境をLinux上の一つのプロセスのように操作できるので、そのような周辺機器もそうストレスなくWindows経由で利用することができそうです。その意味で、VNCは新たな可能性を開いてくれた気がします。

おすすめ記事

記事・ニュース一覧