I am writing NIO2 server, and I need to make asynchronous read operations on an AsynchronousSocketChannel, each of these operations consists of reading an integer, and further reading from the same channel number of bytes equal to this integer. Problem is, when I put two or more CompletionHandler's on channel in a row (cause there are requests for multiple reading operations), and first of these handlers gets fired, my further reading code in complete()
method of the first handler cant work properly, because second handler gets fired instantly when there's info on channel. How can I block channel 'til further reading complete()
completes without Future
thing? I cant use Future cause I need to put handler to the socket and then pass to the other tasks.
for (final Map.Entry<String, AsynchronousSocketChannel> entry : ipSocketTable.entrySet()) {
try {
final AsynchronousSocketChannel outSocket = entry.getValue();
synchronized (outSocket) {
final ByteBuffer buf = ByteBuffer.allocateDirect(9);
outSocket.read(buf, null, new DataServerResponseHandler(buf, outSocket, resultTable, server, entry.getKey()));
}
} catch (Exception e) {
}
}
Here is DataServerResponseHandler class:
class DataServerResponseHandler implements CompletionHandler<Integer, Void> {
private ConcurrentHashMap<String, Boolean> resultTable = null;
private AsynchronousSocketChannel channel = null;
private TcpServer server;
private String ip;
private ByteBuffer msg;
public DataServerResponseHandler(ByteBuffer msg, AsynchronousSocketChannel channel,
ConcurrentHashMap<String, Boolean> resultTable, TcpServer server, String ip) {
this.msg = msg;
this.channel = channel;
this.resultTable = resultTable;
this.server = server;
this.ip = ip;
}
@Override
public void completed(Integer result, Void attachment) {
try {
msg.rewind();
int resultCode = msg.get() & 0xff;
int ipOne = msg.get() & 0xff;
int ipTwo = msg.get() & 0xff;
int ipThree = msg.get() & 0xff;
int ipFour = msg.get() & 0xff;
int length = msg.getInt();
msg.rewind();
ByteBuffer buf = ByteBuffer.allocateDirect(length);
channel.read(buf).get();
buf.rewind();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void failed(Throwable exc, Void attachment) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}