问题
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