我正在尝试运行最简单的仅接受连接的NIO服务器。

public static void main(String[] args) throws IOException{
    Selector selector = Selector.open();
    ServerSocketChannel serverChannel = ServerSocketChannel.open();
    serverChannel.configureBlocking(false);
    serverChannel.socket().bind(new InetSocketAddress("localhost", 1456));
    serverChannel.register(selector, SelectionKey.OP_ACCEPT);
    while (true) {
        try {
            selector.select();
            Iterator<SelectionKey> keys = selector.selectedKeys().iterator();
            while (keys.hasNext()) {
                SelectionKey key = keys.next();
                if (key.isAcceptable())
                    accept(key, selector);
            }
        } catch (IOException e) {
            System.err.println("I/O exception occurred");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

private static void accept(SelectionKey key, Selector selector) throws IOException{
    ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
    SocketChannel channel = serverChannel.accept();
    channel.configureBlocking(false);         //<------- NPE Here
    channel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
    channel.setOption(StandardSocketOptions.TCP_NODELAY, true);
    channel.register(selector, SelectionKey.OP_READ);
}


和最简单的I / O客户端:

 public static void main(String[] ars) throws IOException{
        Socket s = new Socket("localhost", 1456);
        OutputStream ous = s.getOutputStream();
        InputStream is = s.getInputStream();
        while (true) {
            ous.write(new byte[]{1, 2, 3, 3, 4, 5, 7, 1, 2, 4, 5, 6, 7, 8});
            is.read();
        }
    }


当我运行这两个过程时,会得到一堆NullPointterExceeption

客户端第一次连接时,可以。我们检索密钥,获取频道并接受传入的连接。

但是由于我不清楚这个问题,原因是我一直在检索可接受的密钥并尝试接受更多的密钥。 SocketChannel channel = serverChannel.accept();为空,我得到NPE

但是,为什么总是向我通知接受的密钥?我做错什么了?

最佳答案

处理后,需要从所选集中删除每个SelectionKey。否则,即使尚未真正准备就绪,您仍将再次得到同一事件:因此,例如accept()将返回null。

您需要查看一个教程。只是弥补没有好处。请参阅Oracle NIO教程。

10-04 12:10