Java NIO nonblocking: how to refuse incoming connections?
connection, java, nio, nonblocking
Solution
There is no way to accomplish that, but I doubt that that's what you really want, or at least what you really should do.
If you want to stop accepting connections, change the interestOps in the server socket channel's selection key to zero, and change it back to `OP_ACCEPT` when you are ready to accept again. In the interim, `isAcceptable()` will never be true, so the problem you describe won't occur.
However that won't cause further connections to be refused: it will just leave them on the backlog queue where in my opinion and that of the designers of TCP they belong. There will be another failure behaviour if the backlog queue fills up: its effect in the client is system-dependent: connection refusals and/or timeouts.
Problem
I'm trying to use server side code based on java NIO(non blocking) from 'The Rox Java NIO Tutorial'. There are lot of incoming socket connections and I would like to accept only 100. So if there are 100 active connections then new ones should be rejected/refused. But how to do that? There is only method ServerSocketChannel.accept() which returns SocketChannel object. Using that object I can call socketChannel.socket().close(), but connection is already open. Here is part of the code: ``` @Override public void run() { while (true) { try { // Wait for an event one of the registered channels this.selector.select(); // Iterate over the set of keys for which events are available Iterator selectedKeys = this.selector.selectedKeys().iterator(); while (selectedKeys.hasNext()) { SelectionKey key = (SelectionKey) selectedKeys.next(); selectedKeys.remove(); if (!key.isValid()) { continue; } // Check what event is available and deal with it if (key.isAcceptable()) { this.accept(key); } else if (key.isReadable()) { this.read(key); } else if (key.isWritable()) { this.write(key); } } } catch (Exception e) { logger.warn("Reading data", e); } } } ``` and accept() mehod: ``` private void accept(SelectionKey key) throws IOException { // For an accept to be pending the channel must be a server socket channel. ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel(); // Accept the connection and make it non-blocking if (noOfConnections < MAX_CONNECTIONS) { SocketChannel socketChannel = serverSocketChannel.accept(); Socket socket = socketChannel.socket(); socket.setKeepAlive(true); socketChannel.configureBlocking(false); // Register the new SocketChannel with our Selector, indicating // we'd like to be notified when there's data waiting to be read socketChannel.register(this.selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);//listener for incoming data: READ from client, WRITE to client noOfConnections++; logger.info("Accepted: " + socket.getRemoteSocketAddress().toString()); } else { // REJECT INCOMING CONNECTION, but how? logger.warn("Server is full: " + noOfConnections + " / " + MAX_CONNECTIONS); } } ``` If connection is not accepted then accept() method is being called over and over. Thanks for help!