Java nio Channel.register выбрасывает исключение IllegalArgumentException - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь выбрать серверный сокет канала java nio, как показано ниже:

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

Затем простой клиент, такой как:

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

Сначала я запускаю сервер, а затем клиент,сервер будет подключен и выдаст исключение, как показано ниже:

..................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)

Так что же произошло, когда клиент подключается?Почему функция регистрации выдает исключение и как это исправить?

Ответы [ 2 ]

0 голосов
/ 04 декабря 2018

SocketChannel имеет допустимую опцию только для OP_READ, OP_WRITE, OP_CONNECT.Пожалуйста, проверьте SocketChannel.validOps ()

0 голосов
/ 04 декабря 2018

Если произойдет сбой в channel.register(selector, SelectionKey.OP_ACCEPT), вам придется изменить его на

channel.register(selector, SelectionKey.OP_READ);

Только ServerSocketChannel поддерживает SelectionKey.OP_ACCEPT.

listenChannel.accept() создать новый канал, который поддерживает операции чтения и записи.

...