Java's NIO package is touted as an improvement over the original networking APIs with enhancements to avoid blocking situations through the use of buffers.
You can read more about Java NIO at this Wikipedia article [http://en.wikipedia.org/wiki/New_I/O]. This article presents a simple implementation of a Server implemented using the NIO API. It consists of three classes:
- A listener Thread - loops accepting incoming connections.
- A reader Thread - iterates over client connections processing any input.
- A 'Server' singleton class which simply aggregates and starts the threads.

The Listener
The constructor of this Thread binds a ServerSocketChannel to the local network interface.
public ListenerThread(LinkedListconnections ) throws IOException { this.connections = connections; this.connectSelector = Selector.open(); InetSocketAddress address = new InetSocketAddress(Server.LISTEN_PORT); serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); serverSocketChannel.socket().bind(address); System.out.println("Listener bound to " + address); serverSocketChannel.register(this.connectSelector, SelectionKey.OP_ACCEPT);
} |
The run() method then loops infinitely, checking for new connections.
while (true) { try { connectSelector.select(); for( SelectionKey key : connectSelector.selectedKeys() ) { connectSelector.selectedKeys().remove(key); SocketChannel incomingChannel = ((ServerSocketChannel) key.channel()).accept(); connections.add( incomingChannel ); Server.getInstance().wakeReader(); } } catch (Exception ex) { ex.printStackTrace(); } }
|
The Reader
The run() method loops infinitely, checking for input.
while (true) { SocketChannel channel = null; try { while ( (connections.size() > 0) && (null != (channel = connections.removeFirst())) ) { channel.configureBlocking(false); channel.register(readSelector, SelectionKey.OP_READ, new StringBuffer()); } if ( readSelector.select() > 0) { Set readyKeys = readSelector.selectedKeys(); for (SelectionKey key : readyKeys ) { readyKeys.remove(key); readRequest(key); } } } catch (Exception e) { e.printStackTrace(); if( channel != null ) connections.remove(channel); } }
|
When the Server is running, a telnet conection to it will read in characters and return the '#' character for each character sent.
Here is the full source for this example.