如何断开客户端与NIO服务器套接字的连接

时间:2014-12-28 08:28:30

标签: java sockets nio

我正在开发一个与许多客户端连接的服务器。我需要知道客户端何时与服务器断开连接。因此每个客户端都会向服务器发送特定字符。如果两秒钟后没有收到该字符,那么我应该断开服务器与客户端的连接(为该客户端释放已分配的资源)。

这是我服务器的主要代码:

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);
        }       
    }
}

第一个问题是,我用于识别在线客户端(每秒发送特定消息)的方式是否是一种好方法?

如果它是好的,我如何检测到SelectionKey与女性客户端有关,那么如何断开密钥与服务器的连接?

2 个答案:

答案 0 :(得分:2)

  

第一个问题是,我用于识别在线客户端(每秒发送特定消息)的方式是否是一种好方法?

不是回显服务器的情况。在许多情况下,您需要的只是适当地识别流的结束和连接失败。

  

如何通过SelectionKey检测与哪个客户端相关

SelectionKey有一个通道,通道有一个套接字,Socket有一个远程IP地址:port。这就是你所需要的一切。

  

然后如何断开密钥与服务器的连接?

当您从read()方法获得-1时关闭频道,或者在阅读或写作时获得IOException

答案 1 :(得分:1)

  

我用于识别在线客户端(每秒发送特定消息)的方式是否是一种好方法?

是的,它被称为心跳。

  

如何使用SelectionKey检测与女性客户端有关,然后如何从服务器断开密钥?

您可以附加一个包含有关频道所需信息的对象。注册频道时请包括此内容。