简体   繁体   中英

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?

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.

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

Yes, it is called a heartbeat.

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

You can attach an object which has all the information need regarding a channel. You include this when you register the channel.

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