第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 (Iteratoriterator = 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メソッドは待機することなくデータを受信することができます。