ノンブロッキングモードとObjectInputStream
this.selector = Selector.open(); ServerSocketChannel serverChannel = ServerSocketChannel.open(); serverChannel.socket().setReuseAddress(true); serverChannel.socket().bind(new InetSocketAddress(port)); serverChannel.configureBlocking(false); serverChannel.register(selector, SelectionKey.OP_ACCEPT); while(true) { selector.select(); Set<SelectionKey> keys = selector.selectedKeys(); for (Iterator<SelectionKey> it = keys.iterator(); it.hasNext(); ) { SelectionKey key = it.next(); it.remove(); if (key.isAcceptable()) { doAccept((ServerSocketChannel)key.channel()); } else { if (key.isReadable()) { doRead((SocketChannel)key.channel()); } } } } private void doAccept(ServerSocketChannel deamonChannel) throws IOException { SocketChannel channel = deamonChannel.accept(); channel.configureBlocking(false); channel.register(this.selector, SelectionKey.OP_READ); }
アプリケーション間のソケット通信ででオブジェクトをやりとりしようと思い、上のような感じのノンブロッキングモードでaccept後、使用可能になったソケットチャネルを使ってクライアント側からObjectOutputStream経由で送信されてくるオブジェクトを、ObjectInputStreamで復元しようと思ったんだが、
private void doRead(SocketChannel channel) throws IOException {
ObjectInputStream oi =
new ObjectInputStream(channel.socket().getInputStream());
try {
Object o = oi.readObject();
〜
} catch (ClassNotFoundException e) {
〜
}
}
doReadメソッド冒頭のchannel.socket().getInputStream()でjava.nio.channels.IllegalBlockingModeExceptionがスローされる。よく考えたら当たり前だよなあ。
オブジェクトストリームの書き出しと復旧はNIO以前に考えられたクラスなのだし、この場合は普通のブロッキングモード+マルチスレッドで処理すべきなのかな。