//******* Reverse server using new I/O and channels import java.nio.ByteBuffer; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.channels.Selector; import java.nio.channels.SelectionKey; import java.net.InetSocketAddress; import java.util.Iterator; public class ReverseServerNB { public static void main(String[ ] args) throws Exception { // Create a non-blocking channel for accepting clients. ServerSocketChannel a_chan = ServerSocketChannel.open(); a_chan.configureBlocking(false); // Bind the channel's associated socket to a port. InetSocketAddress addr = new InetSocketAddress(port); a_chan.socket().bind(addr); // Register the channel as a "client acceptor." Selector selector = Selector.open(); a_chan.register(selector, SelectionKey.OP_ACCEPT); // Await clients and process their requests. while (true) { // Select ready channel. Returns immediately if // there's a ready channel. selector.select(); // Some channel is ready so iterate over the // channels registered with the selector. Iterator it = selector.selectedKeys().iterator(); // Process each selection: SelectionKey identifies // the ServerSocketChannel that accepts clients or // a SocketChannel for reading/writing. while (it.hasNext()) { // Key for a selected channel. SelectionKey key = (SelectionKey) it.next(); it.remove(); // from underlying collection // Are there clients to be accepted? if (key.isAcceptable()) { // Get a reference to the ServerSocketChannel. ServerSocketChannel b_chan = (ServerSocketChannel) key.channel(); // Then get the associated SocketChannel. SocketChannel read_chan = b_chan.accept(); // Check on accept() return value if (read_chan == null) continue; // OK, a connection accepted else { read_chan.configureBlocking(false); // Register the socket channel for reads. read_chan.register(selector, SelectionKey.OP_READ); } } // Are there request data to read? if (key.isReadable()) { // Get the associated SocketChannel to read // the request and write the response. SocketChannel chan = (SocketChannel) key.channel(); ByteBuffer buff = ByteBuffer.allocate(buff_limit); // Read the request bytes. while (chan.read(buff) > 0) ; // Reverse string and wrap in a ByteBuffer. // The trim() removes extraneous bytes. String s = new String(buff.array()).trim(); s = new StringBuffer(s).reverse().toString(); ByteBuffer out = ByteBuffer.wrap(s.getBytes()); while (out.hasRemaining()) chan.write(out); chan.close(); // also cancels key } } } } private static final int port = 3333; private static final int buff_limit = 512; }