Does Selector.close() closes all client sockets?

六眼飞鱼酱① 提交于 2020-01-03 18:39:12

问题


I am new to nio sockets, I have written a server using nio sockets and now I am trying to write shutdown hook to make sure a graceful exit by cleaning up resources.

My question is does Selector.close() method closes all client sockets? if not please let me know how can I access all the client sockets without having a separate list of them.

Java Doc says following for selector.close() method

Closes this selector.

If a thread is currently blocked in one of this selector's selection methods then it is interrupted as if by invoking the selector's wakeup method.

Any uncancelled keys still associated with this selector are invalidated, their channels are deregistered, and any other resources associated with this selector are released.

If this selector is already closed then invoking this method has no effect.

After a selector is closed, any further attempt to use it, except by invoking this method or the wakeup method, will cause a ClosedSelectorException to be thrown.

Above description uses word "deregistered" which gives a feeling that it does not close the sockets but just removes their mapping from selector.


回答1:


No, it only closes the Selector.

You can access all the registered socket keys via Selector.keys(), before you close the selector.




回答2:


Thanks to EJP who pointed me in correct direction but one has to keep in mind that keys contains serverSocketChannel as well. Anyway following code worked for me on shutdown in case you are looking for a piece of code.

if(this.serverChannel != null && this.serverChannel.isOpen()) {

    try {

        this.serverChannel.close();

    } catch (IOException e) {

        log.error("Exception while closing server socket");
    }
}

try {

    Iterator<SelectionKey> keys = this.selector.keys().iterator();

    while(keys.hasNext()) {

        SelectionKey key = keys.next();

        SelectableChannel channel = key.channel();

        if(channel instanceof SocketChannel) {

            SocketChannel socketChannel = (SocketChannel) channel;
            Socket socket = socketChannel.socket();
            String remoteHost = socket.getRemoteSocketAddress().toString();

            log.info("closing socket {}", remoteHost);

            try {

                socketChannel.close();

            } catch (IOException e) {

                log.warn("Exception while closing socket", e);
            }

            key.cancel();
        }
    }

    log.info("closing selector");
    selector.close();

} catch(Exception ex) {

    log.error("Exception while closing selector", ex);
}


来源:https://stackoverflow.com/questions/24543675/does-selector-close-closes-all-client-sockets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!