import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.CompletionHandler; public class EchoAsyncProtocol implements TCPProtocol { private int bufSize; // Size of I/O buffer public EchoAsyncProtocol(int bufSize) { this.bufSize = bufSize; } public void handleAccept(final AsynchronousSocketChannel clntChan) throws IOException { ByteBuffer buf = ByteBuffer.allocateDirect(bufSize); clntChan.read(buf, buf, new CompletionHandler() { public void cancelled(ByteBuffer v) { // Not handled } public void completed(Integer bytesRead, ByteBuffer buf) { try { handleRead(clntChan, buf, bytesRead); } catch (IOException e) { // Not handled } } public void failed(Throwable ex, ByteBuffer v) { try { clntChan.close(); } catch (IOException e) { // Ignored } } }); } public void handleRead(final AsynchronousSocketChannel clntChan, ByteBuffer buf, int bytesRead) throws IOException { if (bytesRead == -1) { // Did the other end close? clntChan.close(); } else if (bytesRead > 0) { buf.flip(); // prepare to write clntChan.write(buf, buf, new CompletionHandler() { public void cancelled(ByteBuffer buf) { // Not handled } public void completed(Integer bytesWritten, ByteBuffer buf) { try { handleWrite(clntChan, buf); } catch (IOException e) { // Not handled } } public void failed(Throwable ex, ByteBuffer buf) { try { clntChan.close(); } catch (IOException e) { // Ignored } } }); } } public void handleWrite(final AsynchronousSocketChannel clntChan, ByteBuffer buf) throws IOException { if (buf.hasRemaining()) { // More to write clntChan.write(buf, buf, new CompletionHandler() { public void cancelled(ByteBuffer buf) { // Not handled } public void completed(Integer bytesWritten, ByteBuffer buf) { try { handleWrite(clntChan, buf); } catch (IOException e) { // Not handled } } public void failed(Throwable ex, ByteBuffer buf) { try { clntChan.close(); } catch (IOException e) { // Ignored } } }); } else { // Back to reading buf.clear(); clntChan.read(buf, buf, new CompletionHandler() { public void cancelled(ByteBuffer v) { // Not handled } public void completed(Integer bytesRead, ByteBuffer buf) { try { handleRead(clntChan, buf, bytesRead); } catch (IOException e) { // Not handled } } public void failed(Throwable ex, ByteBuffer v) { try { clntChan.close(); } catch (IOException e) { // Ignored } } }); } } }