Java Selector select () всегда возвращает последний прочитанный ключ - PullRequest
2 голосов
/ 28 июня 2010

Я пытаюсь написать TCP-сервер, который читает данные, отправленные клиентом.Я хочу оставить клиентское соединение открытым после чтения, чтобы иметь возможность читать любые последующие отправленные данные.

Код, который я выполняю ниже:

    while(true) {
        try {
            int keysSelected = selector.select();

            System.out.println("keysSelected = " + keysSelected);
            if (keysSelected < 1) {
                continue;                    
            }
        } catch (IOException e) {
            e.printStackTrace();
            break;
        }


        Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator();

        while(keyIterator.hasNext()) {
            SelectionKey key = keyIterator.next();
            keyIterator.remove();

            if (key.isAcceptable()) {
                processAcceptRequest(selector, key);
            } else if (key.isReadable()) {
                processQueryRequest(key);
            }
        }
    }

Проблема, с которой я сталкиваюсьчто до того, как подключатся какие-либо клиенты, вызов select в селекторе блокируется.После того, как первый клиент подключится и запишет данные на сервер, select непрерывно возвращает ключ OP_READ, даже если нет данных для чтения?Что я делаю не так?

Код для чтения:

private void processQueryRequest(SelectionKey key) {
    ByteBuffer byteBuffer = ByteBuffer.allocate(32);

    SocketChannel clientChannel = (SocketChannel) key.channel();

    try {
        byteBuffer.clear();

        while(clientChannel.read(byteBuffer) > 0) {
            byteBuffer.flip();

            Charset charset = Charset.forName("UTF-8");
            CharBuffer charBuffer = charset.decode(byteBuffer);

            System.out.println(charBuffer.toString());
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

С уважением, Брайан

1 Ответ

0 голосов
/ 28 июня 2010

Вам нужно позвонить compact() после того, как вы позвоните flip() и обработаете полученные данные.Вы никогда этого не делаете, поэтому вы заполняете буфер, поэтому read() возвращает ноль, поэтому вы возвращаетесь в цикл select(), но в буфере приема сокета все еще есть ожидающие данные.

...