Search code examples
javasocketsnio

How to disconnect a client from NIO server socket


I am developing a server that is connected with many clients. I need to know when a client is disconnecting from server. So each client is sending a specific character to the server. If the character is not received after two seconds then I should disconnect the server from the client (releasing allocated resource for this client).

This is the main code of my server:

public EchoServer(int port) throws IOException {
    this.port = port;
    hostAddress = InetAddress.getByName("127.0.0.1");
    selector = initSelector();
    loop();
}

private Selector initSelector() throws IOException {
    Selector socketSelector = SelectorProvider.provider().openSelector();

    ServerSocketChannel serverChannel = ServerSocketChannel.open();
    serverChannel.configureBlocking(false);

    InetSocketAddress isa = new InetSocketAddress(hostAddress, port);
    serverChannel.socket().bind(isa);
    serverChannel.register(socketSelector, SelectionKey.OP_ACCEPT);

    return socketSelector;
}

private void loop() {
    for (;true;) {
        try {
            selector.select();
            Iterator<SelectionKey> selectedKeys = selector.selectedKeys()
                    .iterator();
            while (selectedKeys.hasNext()) {
                SelectionKey key = selectedKeys.next();
                selectedKeys.remove();

                if (!key.isValid()) {
                    continue;
                }

                // Check what event is available and deal with it
                if (key.isAcceptable()) {
                    accept(key);
                } else if (key.isReadable()) {
                    read(key);
                } else if (key.isWritable()) {
                    write(key);
                }
            }
            Thread.sleep(1000);
            timestamp++;
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }       
    }
}

The first question is that, whether the way that I used in order to recognizing online clients (sending specific message every second) is a good approach or not?

If it is good, how can I detect with SelectionKey is related to witch client and then how can I disconnect the key from server?


Solution

  • The first question is that, whether the way that I used in order to recognizing online clients (sending specific message every second) is a good approach or not?

    Not in the case of an echo server. In many cases such as this, all you need is to recognize end of stream and connection failure appropriately.

    how can I detect with SelectionKey is related to which client

    The SelectionKey has a channel, the channel has a socket, and the Socket has a remote IP address:port. That's all you need.

    and then how can I disconnect the key from server?

    Close the channel when you get -1 from the read() method, or any IOException when reading or writing.