2006 年 12 月 14 日 23 時 51 分

TCP のセッション


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


RFB は、双方向に通信ができる環境で利用できる。
このような環境を Java で表すとすれば、
InputStream と OutputStream のペアで表現される事になる。

さて、VNCServer がクライアントとの接続を確立した後は、
クライアントとの通信用のソケットを使って処理するが、
RFB の世界にソケットを持ち込みたくはない。

そこで、とりあえず VNCSession というクラスを作り、
クライアントとの通信用のソケットから、
InputStream と OutputStream を取り出すコードを書こう。

========== VNCSession.java ==========

package jp.loafer.rfbdemo;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

/**
* VNC クライアントとの通信
* @author kes
*/
public class VNCSession implements Runnable {

    /**
     * {@link VNCSession} のインスタンスを作成。
     * @param client 接続してきたクライアントソケット。
     */
    public VNCSession(Socket client) {
        socket = client;
    }

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

        try {
           
            InputStream in = socket.getInputStream();
            OutputStream out = socket.getOutputStream();

            // メイン処理が来る予定
           
        } catch (Exception e) {

            e.printStackTrace(System.err);

        } finally {

            try {
                socket.close();
            } catch (IOException e) {
                // 例外無視
            }
           
        }

    }
   
    private Socket socket;

}

========== end of VNCSession.java ==========

これも大したことをしていないクラスだ。
コンストラクタで Socket を受け取り、
run ではそれを使って通信を行う。

Runnable#run ではソケット固有の処理をしている。
getInputStream, getOutputStream を呼び出せば、
通信に使える汎用の入出力ストリームが得られる。
また、例外の捕捉とソケットを閉じる処理を入れておけば、
ソケットに依存する部分はクラスから分離できる。

後は、上記で得られた入出力ストリームを元にして、
RFB の処理を行うクラスを呼べばよい訳だ。
上記では「メイン処理が来る予定」とコメントにしている。

では、これを使うように VNCServer#run を修正しよう。

========== VNCServer#run ==========

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

        while (!socket.isClosed()) {

            try {

                Socket client = socket.accept();
                VNCSession session = new VNCSession(client);
                new Thread(session, "VNCSession").start();

            } catch (IOException e) {

                e.printStackTrace(System.err);

            }

        }

    }

========== end of VNCServer#run ==========

クライアントとのセッションを別スレッドで走らせる。
例によって、スレッドは放りっぱなしである。

ところで、このような書き方は、
Java に慣れた方には違和感があるかもしれない。
ハンドラを分離し、インタフェースを定め、
洗練された設計をすることもできるからだ。

しかしながら、今回は実装を目的としているため、
美しいとか再利用性とかは考えずに、
直接的なコーディングで進めようと思っている。



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