St.Antario
St.Antario

Reputation: 27425

The simplest NIO-server example

I'm trying to run the simplest NIO-server which just accepts connections.

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

And the simplest I/O client:

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

When I run both this processes I get a bunch of NullPointterExceeptions.

When the client connects for the first time, it's okay. We retrieve the key, get the channel and accept the incoming connection.

But the problem is for some unclear to me reason I keep retrieving the key that is acceptable and try to accept more. The SocketChannel channel = serverChannel.accept(); is null and I get NPE.

But why am I always notified with the key that is accepted? What did I do wrong?

Upvotes: 0

Views: 350

Answers (1)

user207421
user207421

Reputation: 311008

You need to remove each SelectionKey from the selected set after you process it. Otherwise you will get the same event again, even though it isn't really ready: so for example accept() will return null.

You need to look at a tutorial. No good just making it up. See the Oracle NIO tutorial.

Upvotes: 2

Related Questions