Search code examples
javasocketsserverniochannel

Java nio Channel.register throws out IllegalArgumentException


I'm trying java nio's socket server channel and selector as below:

try { // server side main function
    ServerSocketChannel listenChannel = ServerSocketChannel.open();
    listenChannel.socket().bind(new InetSocketAddress(12112));
    Selector selector = Selector.open();
    listenChannel.configureBlocking(false);
    listenChannel.register(selector, SelectionKey.OP_ACCEPT);
    while (true) {
        if (selector.select(TIMEOUT) == 0) {
            System.out.print(".");
            continue;
        }
        Iterator<SelectionKey> it = selector.selectedKeys().iterator();
        while (it.hasNext()) {
            SelectionKey key = it.next();
            it.remove();
            if (key.isAcceptable()) {
                SocketChannel channel = listenChannel.accept();
                channel.configureBlocking(false);
                SelectionKey connKey = channel.register(selector, SelectionKey.OP_ACCEPT);
            }
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}

Then a simple client like:

try {
    SocketChannel socketChannel = SocketChannel.open();
    socketChannel.connect(new InetSocketAddress("127.0.0.1", 12112));

    ByteBuffer writeBuffer = ByteBuffer.allocate(32);
    ByteBuffer readBuffer = ByteBuffer.allocate(32);

    writeBuffer.put("hello".getBytes());
    writeBuffer.flip();

    while (true) {
        writeBuffer.rewind();
        socketChannel.write(writeBuffer);
        readBuffer.clear();
        socketChannel.read(readBuffer);
    }
} catch (IOException e) {
}

First I start the server and then client, the server will be connect and throw exception like below:

..................java.lang.IllegalArgumentException
at java.nio.channels.spi.AbstractSelectableChannel.register(AbstractSelectableChannel.java:199)
at java.nio.channels.SelectableChannel.register(SelectableChannel.java:280)
at NIOServer.main(myServer.java:32)

So what happened when client connects? Why register function throws out exception and how to fix it?


Solution

  • The SocketChannel has the valid option only for OP_READ,OP_WRITE,OP_CONNECT. Please check SocketChannel.validOps()