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: }