NIOとマルチキャスト

多くの開発者がずっと困っていた問題が,java.nio.channelsパッケージがインターネットプロトコル(IP)マルチキャストをサポートしていないことでした.NIO.2の早期ドラフトレビュー仕様では,この問題をDatagramChannelクラスにマルチキャストサポートを追加することで解決したことがわかるでしょう.ここでは,DatagramChannelをオープンして,このチャネルのソケットをローカルのポートにバインドしてから,そのネットワークインタフェースをこのソケット経由でマルチキャストデータグラムを送信できるように設定し,その同じインタフェースをあるマルチキャストグループに参加させる簡単な例を示します.

NetworkInterface interf = NetworkInterface.getByName("eth0");
InetAddress group = InetAddress.getByName("225.0.0.100");

DatagramChannel dc = DatagramChannel.open(ProtocolFamily.INET)
    .setOption(SocketOption.SO_REUSEADDR, true)
    .bind(new InetSocketAddress(5000))
    .setOption(SocketOption.IP_MULTICAST_IF, interf);

MembershipKey key = dc.join(group, interf); 

一旦チャネルがグループに参加すれば,ユニキャストデータグラムを読んだり受信するように,マルチキャストデータグラムを読んだり受信できます.
この例で最も重要な点は,このチャネルをオープンするためのstaticファクトリメソッドでプロトコルファミリーを指定していることです.この例では,チャネルはIPv4のソケットです.今までのAPIではプロトコルファミリーは透過であり,java.netパッケージやjava.nio.channelsパッケージによって作成されるすべてのソケットは,ずっとIPv4かずっとIPv6のどちらか一方でした.IPマルチキャストでは,プロトコルファミリがそのソケットが参加するマルチキャストグループのアドレス型と一致させることが重要で,そうでなければ,もしソケットがグループに参加したり,オプションを設定したり,マルチキャストデータグラムを受信する場合には,オペレーティングシステムに強く依存してしまいます.従来のjava.net.MulticastSocketクラスでは,このような問題に非常に困っていました.別の興味深い点は,チャネルのソケットをバインドしてから,直接ソケットオプションを設定していることです.これで使いにくく,わかりにくいソケットアダプタは必要なくなったので,チャネルのソケットを設定する時にjava.netパッケージのソケットAPIを混在する必要はありません.
この例では,joinメソッドが返すMembershipKeyはグループのメンバーシップを表すトークンです.それは,メンバーシップについての情報を問い合わせるメソッドと,グループのメンバーシップを破棄するための"drop"メソッドを定義しています.
マルチキャストの規格を追っている開発者は,ここ数年はソースフィルタリングを追加するために,この分野のRFCが更新されていて,現在はほとんどの近代的なオペレーティングシステムでサポートされていることを知っているでしょう.NIO.2の早期ドラフトレビュー仕様では,ソースフィルタリングに対して基本的なサポートを追加しています.次のコードは,ある特定のIPソースアドレスから送られたマルチキャストデータグラムを受信するためだけに(これは別名INCLUDEモードフィルタリングとして知られています),あるマルチキャストグループに参加する方法を示しています.

MembershipKey key = dc.join(group, interf, source);

次のEXCLUSIVEモードフィルタリングでは,参加したグループで特定のIPソースアドレスからのマルチキャストデータグラム以外はすべて受信します.

MembershipKey key = dc.join(group, interf).block(source1).block(source2);

ここでは,java.nio.channelsパッケージに追加したマルチキャストサポートについて簡単に説明しました.この話題に興味を持った人達は,ドラフト仕様にもっと詳しく書かれているので,そちらを見てください.
(Alan Bateman "Multicasting with NIO"を翻訳.)