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