このアーカイブは同期化されません。 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 による接続が確立されていることは確認できた。