01: //******* Reverse server using new I/O and channels 02: import java.nio.ByteBuffer; 03: import java.nio.channels.ServerSocketChannel; 04: import java.nio.channels.SocketChannel; 05: import java.nio.channels.Selector; 06: import java.nio.channels.SelectionKey; 07: import java.net.InetSocketAddress; 08: import java.util.Iterator; 09: 10: public class ReverseServerNB { 11: public static void main(String[ ] args) throws Exception { 12: // Create a non-blocking channel for accepting clients. 13: ServerSocketChannel a_chan = ServerSocketChannel.open(); 14: a_chan.configureBlocking(false); 15: 16: // Bind the channel's associated socket to a port. 17: InetSocketAddress addr = new InetSocketAddress(port); 18: a_chan.socket().bind(addr); 19: // Register the channel as a "client acceptor." 20: Selector selector = Selector.open(); 21: a_chan.register(selector, SelectionKey.OP_ACCEPT); 22: 23: // Await clients and process their requests. 24: while (true) { 25: // Select ready channel. Returns immediately if 26: // there's a ready channel. 27: selector.select(); 28: // Some channel is ready so iterate over the 29: // channels registered with the selector. 30: Iterator it = selector.selectedKeys().iterator(); 31: // Process each selection: SelectionKey identifies 32: // the ServerSocketChannel that accepts clients or 33: // a SocketChannel for reading/writing. 34: while (it.hasNext()) { 35: // Key for a selected channel. 36: SelectionKey key = (SelectionKey) it.next(); 37: it.remove(); // from underlying collection 38: // Are there clients to be accepted? 39: if (key.isAcceptable()) { 40: // Get a reference to the ServerSocketChannel. 41: ServerSocketChannel b_chan = 42: (ServerSocketChannel) key.channel(); 43: // Then get the associated SocketChannel. 44: SocketChannel read_chan = b_chan.accept(); 45: 46: // Check on accept() return value 47: if (read_chan == null) 48: continue; 49: // OK, a connection accepted 50: else { 51: read_chan.configureBlocking(false); 52: // Register the socket channel for reads. 53: read_chan.register(selector, 54: SelectionKey.OP_READ); 55: } 56: } 57: 58: // Are there request data to read? 59: if (key.isReadable()) { 60: // Get the associated SocketChannel to read 61: // the request and write the response. 62: SocketChannel chan = 63: (SocketChannel) key.channel(); 64: ByteBuffer buff = 65: ByteBuffer.allocate(buff_limit); 66: 67: // Read the request bytes. 68: while (chan.read(buff) > 0) 69: ; 70: // Reverse string and wrap in a ByteBuffer. 71: // The trim() removes extraneous bytes. 72: String s = new String(buff.array()).trim(); 73: s = new StringBuffer(s).reverse().toString(); 74: ByteBuffer out = ByteBuffer.wrap(s.getBytes()); 75: while (out.hasRemaining()) 76: chan.write(out); 77: chan.close(); // also cancels key 78: } 79: } 80: } 81: } 82: private static final int port = 3333; 83: private static final int buff_limit = 512; 84: }