2006 年 12 月 13 日 23 時 54 分

TCP による RFB サーバ


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


サーバを作る場合、テストにはクライアントが必要なので、
本家の RealVNC クライアントに手伝ってもらう予定だ。

RealVNC は、TCP の上に RFB を実装しているため、
ソケットを使ったプログラミングが必要となる。

TCP では、サーバ側が特定のポートで接続を待機する。
Java では、java.net.ServerSocket クラスを使うと、
受信待機用のソケットを簡単に作ることができる。

そこで、クライアントの接続を待機するクラスを作ろう。
名前は VNCServer とし、java.lang.Runnable を実装する。
ServerSocket クラスはソケット機能を提供するが、
ソケットを動作させるためのスレッドは確保しないので、
クラス自身はスレッドで走らせる必要があるからだ。

========== VNCServer.java ==========

package jp.loafer.rfbdemo;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
* VNC クライアントの接続を待機するサーバ。
* @author kes
*/
public class VNCServer implements Runnable {
   
    /**
     * {@link VNCServer} のインスタンスを作成。
     * @throws IOException
     */
    public VNCServer() throws IOException {
        socket = new ServerSocket(5900);
    }

    /**
     * @see java.lang.Runnable#run()
     */
    public void run() {

        while (!socket.isClosed()) {

           try {

                Socket client = socket.accept();
                System.out.println(client);
                client.close();

            } catch (IOException e) {

                e.printStackTrace(System.err);

            }

        }

    }

    /**
     * ソケットを閉じる。
     * @throws IOException
     */
    public void close() throws IOException {
        socket.close();
    }

    private ServerSocket socket;
}

========== end of VNCServer.java ==========

ええと、スーパー手抜きクラスである。
コンストラクタで ServerSocket を作成し、
Runnable#run でクライアントの接続を捌く。
ここでは println して即閉じているだけだ。

Windows ではディスプレイ番号 0 を使うので、
ポート 5900 で待機することにしよう。

一応、close メソッドも用意した。
run は基本的にエンドレスのループであるため、
ソケットが閉じるタイミングを契機にして抜けるようにする。

では、main でサーバを起動しよう。

========== Application.java ==========

package jp.loafer.rfbdemo;

import java.io.IOException;

/**
* プログラムの起動クラス。
* @author kes
*/
public class Application {

    /**
     * プログラムを実行する。
     * @param args コマンドライン引数。
     */
    public static void main(String[] args) {
       
        try {
       
            new Thread(new VNCServer()).start();

        } catch (IOException e) {

            e.printStackTrace(System.err);

        }

    }

}

========== end of Application.java ==========

スレッドを放りっぱなしでちょいと乱暴だが、まあいいか。

これを実行すると、クライアントを待機するループに入る。
VNC クライアントを起動して localhost に接続しよう。

サーバは、接続を確立すると直後に切断するが、
テストのためにソケットをデバッグ用に書き出している。

VNC クライアント側では予期せぬ事態であるため、
「The connection closed unexpectedly」のエラーとなるが、
クライアントが接続すると、eclipse 側のコンソールには、
以下のようなデバッグ情報が出力されるはずだ。

    Socket[addr=/127.0.0.1,port=2590,localport=5900]
    Socket[addr=/127.0.0.1,port=2592,localport=5900]

TCP による接続が確立されていることは確認できた。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.