2007 年 1 月 16 日 23 時 49 分

ProtocolVersionHandshake クラス


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


汎用処理用のインタフェースの設計ができたので、
RFBSession に詰め込んでいたハンドラを
独立させることを考える。

ハンドシェイクは 2 種類あった。
1 つは、プロトコルバージョンの確定用、
もう 1 つはセキュリティ処理である。

プロトコルバージョンのハンドシェイクは非常に簡単なので、
少し手を加えて汎用的なものにしよう。

========== ProtocolVersionHandshake.java ==========

package jp.loafer.rfb.server;

import java.io.IOException;

import jp.loafer.rfb.RFBContext;
import jp.loafer.rfb.RFBHandler;
import jp.loafer.rfb.io.RFBInputStream;
import jp.loafer.rfb.io.RFBOutputStream;
import jp.loafer.rfb.message.ProtocolVersionMessage;

/**
* サーバ側の ProtocolVersion ハンドシェイク。
* @author kes
*/
public class ProtocolVersionHandshake implements RFBHandler {

    /**
     * {@link ProtocolVersionHandshake} のインスタンスを作成。
     * @param serverVersion サーバのバージョン。
     */
    public ProtocolVersionHandshake(int serverVersion) {
        this(serverVersion, 3003);
    }

    /**
     * {@link ProtocolVersionHandshake} のインスタンスを作成。
     * @param serverVersion サーバのバージョン。
     * @param minimumVersion クライアントに必要な最小バージョン。
     */
    public ProtocolVersionHandshake(int serverVersion, int minimumVersion) {
        this.serverVersion = serverVersion;
        this.minimumVersion = minimumVersion;
    }
       
    /**
     * @see RFBHandler#execute(RFBContext, RFBInputStream, RFBOutputStream)
     */
    public void execute(RFBContext context,
            RFBInputStream in, RFBOutputStream out) throws IOException {

        // サーバのバージョンを送信
        ProtocolVersionMessage serverVersionMessage
                = new ProtocolVersionMessage(serverVersion);
        out.writeMessage(context, serverVersionMessage);
        out.flush();

        // クライアントのバージョンを受信
        ProtocolVersionMessage clientVersionMessage
                = in.readMessage(null, ProtocolVersionMessage.class);

        int version = clientVersionMessage.getVersion();

        // バージョンを検証
        try {

            // 3.5 は 3.3 として扱えと RFB 仕様書に明記してある
            if (version == 3005) version = 3003;

            // 現時点では 3.3, 3.7, 3.8 の 3 種類しかない
            if (version != 3003 && version != 3007 && version != 3008)
                    throw new IOException("Unknown version.");

            if (version > serverVersion || version < minimumVersion)
                throw new IOException("Can't support this version.");

        } catch (IOException ex) {

            // セキュリティの種類メッセージでエラーを通知

            // 一応クライアントの返したバージョンに従う
            if (version < 3007) {
                out.writeU32(0); // 無効
            } else {
                out.writeU8(0); // 0 個はエラーを表す
            }
            out.writeString(ex.getMessage());
            out.flush();

            throw ex;
        }

        // バージョン確定
        context.setVersion(version);

    }

    private int serverVersion;
    private int minimumVersion;
   
}

========== end of ProtocolVersionHandshake.java ==========

サーバによっては、クライアントのバージョンを制限し、
特別な処理を行う必要が生じる可能性もあるため、
コンストラクタで最小のバージョンを指定可能とした。

ProtocolVersionHandshake のインスタンスを作成し、
execute を呼び出すだけでハンドシェイクを行う事ができる。



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