简体   繁体   中英

Java NIO - gracefully closing connection on the client side

When using NIO, I have the following checks on the server side:

            if (key.isReadable()) {
                readBuffer.clear();
                SocketChannel channel = (SocketChannel) key.channel();
                int read = channel.read(readBuffer);
                if (read == -1) {
                    channel.close();
                    channel.keyFor(selector).cancel();
                } else {
                    readBuffer.flip();
                    System.out.println(charset.decode(readBuffer));
                }
            }

However, it is often the case that read will throw java.io.IOException: An existing connection was forcibly closed by the remote host . On the client side, this is what I do to close the connection:

public void close() throws IOException {
    connection.close();
    connection.keyFor(selector).cancel();
    selector.close();
}

If that is not the graceful way, what is?

The server should send a message to the client to close its connection. It can only do this if the buffers are not full, but it will allows the client to gracefully close the connection.

A simpler solution is for the client to expect this exception and handle it silently. However, the poison pill message is more reliable IMHO as you can tell whether the connection was intended to be closed by the server.

BTW The client can send the same message to the server. After sending the message, you might want to wait for the other end to hang up before closing the connection yourself (or timing out)

You get this exception if you have written to the connection after the peer had already closed it. In other words, an application protocol error.

Solution: don't.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM