第113回 ソケットチャンネルの入出力
引き続き「ソケットチャンネルの入出力」です。
今回はDatagramChannelによる通信で受信側のプログラムを実装します。
DatagramChannelもSelectableChannelを継承しているので、非ブロックモードで入出力を行うことができます。
次のサンプルコードは、データを受信するプログラムです。
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.charset.Charset;
import java.util.Iterator;
public class Main {
public static void main(String[] args) {
DatagramChannel datagramChannel = null;
try {
datagramChannel = DatagramChannel.open();
InetSocketAddress inetSocketAddress = new InetSocketAddress(9999);
datagramChannel.socket().bind(inetSocketAddress);
datagramChannel.configureBlocking(false);
Selector selector = Selector.open();
datagramChannel.register(selector, SelectionKey.OP_READ);
while (selector.select() > 0) {
for (Iterator iterator
= selector.selectedKeys().iterator();
iterator.hasNext();) {
SelectionKey selectionKey = iterator.next();
iterator.remove();
if (selectionKey.isReadable()) {
doReceive(selectionKey);
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
datagramChannel.close();
} catch (Exception e) {}
}
}
private static void doReceive(SelectionKey selectionKey) {
DatagramChannel datagramChannel
= (DatagramChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
Charset charset = Charset.forName("Shift-JIS");
try {
datagramChannel.receive(byteBuffer);
byteBuffer.flip();
System.out.println(charset.decode(byteBuffer));
} catch (Exception e) {
e.printStackTrace();
}
}
}
DatagramChannelはconfigureBlockingメソッドで非ブロックモードに設定し、セレクタに登録しています。
DatagramChannelはデータ受信が可能なときにセレクタによって選択されるので、receiveメソッドは待機することなくデータを受信することができます。

