I wrote a chat demo in netty, and this time I’m going to write it in NIO, just to get familiar with Java NIO Selector, The main objects related to Selector are Selector, Channel and SelectionKey. The relationship among the three and the processing process of Selector are shown as follows:



Multiple channels can register with a Selector, calling the channel’s register method and specifying the events to care about.

A thread handles requests from multiple clients:

public class NioTest12 { public static void main(String[] args) throws Exception { int[] ports = new int[5]; ports[0] = 50000; ports[1] = 50001; ports[2] = 50002; ports[3] = 50003; ports[4] = 50004; Selector selector = Selector.open(); for (int i = 0; i < ports.length; i++) { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); / / set to non-blocking mode serverSocketChannel. ConfigureBlocking (false); InetSocketAddress address = new InetSocketAddress(ports[i]); // Bind port serversocketChannel.bind (address); // the channel registers with the selector, and the final channel is wrapped as a SelectionKeyImpl object, which is stored in the selector as an array:  // The list of SelectableChannels serviced by this Selector // protected SelectionKeyImpl[] channelArray; serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println(" Listening port: "+ ports[I]); } while (true) { int numbers = selector.select(); System.out.println("numbers:" + numbers); Set<SelectionKey> selectionKeys = selector.selectedKeys(); System.out.println("selectionKeys:" + selectionKeys); Iterator<SelectionKey> iter = selectionKeys.iterator(); While (ite.hasNext ()) {// SelectionKey holds the association between SelectableChannel and SelectionKey SelectionKey = ite.next ();  if (selectionKey.isAcceptable()) { ServerSocketChannel serverSocketChannel = (ServerSocketChannel)selectionKey.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); iter.remove(); System.out.println(" Get client connection: "+ socketChannel); } else if (selectionKey.isReadable()) { SocketChannel socketChannel = (SocketChannel)selectionKey.channel(); int bytesRead = 0; while (true) { ByteBuffer buffer = ByteBuffer.allocate(512); buffer.clear(); int read = socketChannel.read(buffer); if (read <= 0) { break; } buffer.flip(); socketChannel.write(buffer); bytesRead += read; } system.out. println(" read: "+ bytesRead + ", from:" + socketChannel); iter.remove(); } } } } }Copy the code

Chat Demo server:

public class NioTest13 { public static void main(String[] args) throws Exception { ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); ServerSocket serverSocket = serverSocketChannel.socket(); serverSocket.bind(new InetSocketAddress(8899)); Map<String, SocketChannel> clientMap = new HashMap<>(); Selector selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); while (true) { try { selector.select(); Set<SelectionKey> selectionKeys = selector.selectedKeys(); selectionKeys.forEach(selectionKey -> { final SocketChannel client; try { if (selectionKey.isAcceptable()) { ServerSocketChannel server = (ServerSocketChannel)selectionKey.channel(); client = server.accept(); client.configureBlocking(false); client.register(selector, SelectionKey.OP_READ); String key = "[" + UUID.randomuuid ().toString() +"] "; clientMap.put(key, client); } else if (selectionKey.isReadable()) { client = (SocketChannel)selectionKey.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1024); int count = client.read(readBuffer); if (count > 0) { readBuffer.flip(); Charset charset = Charset.forName("utf-8"); String receivedMessage = String.valueOf(charset.decode(readBuffer).array()); System.out.println(client + ": " + receivedMessage); String senderKey = null; for (Map.Entry<String, SocketChannel> entry : clientMap.entrySet()) { if (client == entry.getValue()) { senderKey = entry.getKey(); break; } } for (Map.Entry<String, SocketChannel> entry : clientMap.entrySet()) { SocketChannel channel = entry.getValue(); ByteBuffer writeBuffer = ByteBuffer.allocate(1024); writeBuffer.put((senderKey + ": " + receivedMessage).getBytes()); writeBuffer.flip(); channel.write(writeBuffer); } } } } catch (Exception e) { e.printStackTrace(); }}); selectionKeys.clear(); } catch (Exception e) { e.printStackTrace(); }}}}Copy the code