Java の Socket オプション
JDK 1.1 のソケットクラスの javadoc はここにあります。
C の方法
C でプログラミングする場合、次の行でシステムコールを使用してオプションを設定します。
setsockopt(int fd, int level, int optval, void *optdata,
int optdatalen);
fd = すでに開かれた (おそらく接続された) ソケット fd
level = オプションが適用されるプロトコルスタック (IP, UDP, TCP) のレベル
optval = オプション、CONSTANT
optdata = 特定のオプションにだけ関係するパラメータのオプション依存 sturuct への ptr
Java の方法
C でのオプションセットの方法は、オブジェクト指向プログラミングの型の安全性を欠いています。設定および取得したいオプションは、int として識別され、認定および取得する値は、型がはっきりしない void* になります。間違ったオプション識別子、void* パラメータの間違った型オブジェクトを渡してしまうこと、またはそのパラメータに対して間違ったものを渡してしまうことは簡単に起こりえます。さらに悪いことには、これらエラーのコードも通常はコンパイルされてしまい、エラーは実行時にだけ表示されます。
Java では現在、オプションを設定するときに型を保証する方法を提供しています。各ソケットクラスは、自分がサポートする各オプション用の取得および設定メソッドを持ち、適当な型を取得したり返したりします。ソケットクラスでサポートされるオプション、およびその意味を簡単に説明します。
- TCP_NODELAY
- Nagle アルゴリズムを使用不可にする
- (クライアント) Socket に対して有効
- SO_LINGER
- linger-on-close タイムアウトを指定する
- (クライアント) Socket に対して有効
- SO_TIMEOUT
- ソケット操作をブロックするタイムアウトを指定する (永久にブロックしないこと)
- ソケット Socket、ServerSocket、および DatagramSocket に対して有効
- IP_MULTICAST_IF
- マルチキャストパケットに対して送出するインタフェースを指定する (マルチホームホスト上で)
- MulticastSocket に対して有効
さらに、JDK 1.1 は Socket、ServerSocket および DatagramSocket に対して新しいコンストラクタを提供することにより、このコンストラクタはソケットがバインドするローカルアドレスおよびローカルポートを設定することができ、同様に、クラスはこれらにそのローカルアドレスを公開できます。
JDK 1.1 のソケットクラスについて、全オプションの取得および設定方法の詳細を含めた、完全な javadoc をここに提供します。java で使用したい他のオプションがあれば、ご連絡ください。
補足
Java ではサポートされていない、使用可能な BSD オプションは次のとおりです。
- SO_KEEPALIVE:
このオプションを使用すると、OS は繰り返し接続ピアに ping し、その接続ピアがそこにあることを確認する。この機能は、アプリケーションレベルでもっともうまく処理される。ホスト要件の RFC は 2 時間の ping 間隔を指定するが、これは実際は有用ではない
- MSG_OOB:
帯域内データの前に、帯域外 (out-of-band) または「至急 (urgent)」とマークされたデータが存在する場合に、それを読み込むためにソケット上の read() または recv() に渡すオプション。このオプションを使用する場合は、オプション SO_OOBINLINE (下記) も使用する必要があるが、このオプションが必要というわけではない。これに関する真の問題点は、OOB データを書き込むための対称的な方法を提供する必要があるが、要求されていないということである
- SO_OOBINLINE:
このオプションは OOB データをインラインにし、それを「通常の」データのようにインラインに表示する。これは MSG_OOB と連携して動作する
- RAW/ICMP SOCKETS:
このオプションを使用する理由として、Java で ping を書くことができるということがあるが、それによってセキュリティ上の問題が発生する可能性がある。UNIX コンピュータ上の root でなければならない
実装の詳細
サブクラスが SocketImpl/DatagramSocketImpl でない場合は、この情報は必要ありません。すべての *Socket オブジェクトは、ネイティブコードとのインタフェースとなる内在する SocketImpl/DatagramSocketImpl を持っています。Impl クラスは 2 つのメソッドを実装しオプションをサポートします。
void setOption(int optID, Object val) throws SocketException;
Object getOption(int optID) throws SocketException ;
これは C によく似ています。これらのメソッドはネイティブメソッドに対して糊のような働きをし、ネイティブメソッドを起動する前に型の安全を保証します。
brown@monkey.eng.sun.com