/* * SampleServerNio.java * * java.nio version */ /** * * @author Peter Sutton */ import java.net.*; import java.nio.*; import java.nio.channels.*; import java.nio.charset.*; import java.util.*; public class SampleServerNio { public static void main(String[] args) throws Exception { // An argument is expected - a port number to listen on - check for it if(args.length != 1) { System.err.println("Expected port number on command line"); System.exit(1); } // Create socket channel ServerSocketChannel serverChannel = ServerSocketChannel.open(); // Get the associated socket ServerSocket serverSocket = serverChannel.socket(); // Bind socket to port int port = Integer.parseInt(args[0]); serverSocket.bind(new InetSocketAddress(port)); // Make the channel non-blocking serverChannel.configureBlocking(false); // Create a selector and register the channel with the selector Selector selector = Selector.open(); serverChannel.register(selector, SelectionKey.OP_ACCEPT); while(true) { // wait for something of interest to our selector (n is number // of keys, possibly zero, whose ready-operation sets were // updated) int n = selector.select(); if(n == 0) { continue; } // Create an iterator and examine the keys of interest Iterator iterator = selector.selectedKeys().iterator(); while(iterator.hasNext()) { SelectionKey key = (SelectionKey) iterator.next(); if(key.isAcceptable()) { // Accept a new connection. This gives us a new socket // channel and we need to register that with our selector // also (we're interested in reading on this channel). // (Sometimes get a null channel if nothing available.) SocketChannel channel = ((ServerSocketChannel)key.channel()).accept(); if(channel != null) { System.err.println("Creating new channel"); channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_READ); } } else if(key.isReadable()) { // Get the associated channel SocketChannel channel = (SocketChannel)key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); int count; buffer.clear(); // Read data from the channel try { count = channel.read(buffer); // Can return -1 if end-of-stream } catch (Exception e) { // Assume failure means channel has closed count = -1; } if(count == -1) { System.out.println("Connection closed."); channel.close(); // Selection key will be automatically invalidated } else { // Extract ASCII string from data, convert to upper // case and send it back. Newlines still present // in data - no need to send again. buffer.flip(); String msg = Charset.forName("US-ASCII"). decode(buffer).toString().toUpperCase(); buffer.clear(); buffer.put(msg.getBytes()); buffer.flip(); channel.write(buffer); } } // Done with this element iterator.remove(); } } } }