Java NIO Server - PullRequest
       6

Java NIO Server

6 голосов
/ 14 августа 2011

В настоящее время я работаю на сервере Java NIO (однопоточном) и столкнулся с некоторыми проблемами. Сервер принимает входящие соединения, записывает начальные пакеты (пакет содержит некоторые данные, которые клиент использует для дальнейшей связи) клиентам, но не читает их. Сервер пытается читать только когда я закрываю клиента и, конечно, он возвращает -1.

Принимая соединение, оно регистрируется под:

selectionKey = socketChannel.register(_selector, SelectionKey.OP_READ)

selectionKey.isReadable() возвращает false (так?)

Перед отправкой исходного пакета ops изменяются на:

_selectionKey.interestOps(_selectionKey.interestOps() | SelectionKey.OP_WRITE)

После отправки начального пакета ops изменяются на:

selectedKey.interestOps(selectedKey.interestOps() & ~SelectionKey.OP_WRITE)

Пакет отправляется.

В чем может быть проблема? Может ли это быть связано с клиентом?

Ответы [ 2 ]

6 голосов
/ 14 августа 2011

selectionKey.isReadable() возвращает false (верно?)

Конечно, пока есть данные для чтения или конец потока.

Перед отправкой исходного пакета ops изменяются на:

_selectionKey.interestOps(_selectionKey.interestOps() | SelectionKey.OP_WRITE)

Плохая идея. OP_WRITE почти всегда готов, т. Е. Кроме случаев, когда буфер отправки сокета заполнен, так что вы просто заставите свой метод Selector.select() бездумно вращаться.

Если вы хотите написать на канал, просто пишите. Сделайте это в классическом цикле:

while (buffer.position() > 0)
{
    buffer.flip();
    int count = channel.write(buffer);
    buffer.compact();
    if (count == 0)
    {
        // see below ...
    }
}

Если count равен нулю, вы должны , затем зарегистрироваться на OP_WRITE, выйти из цикла и вернуться к циклу Selector. Если вы вышли из этого цикла без этого, отмените регистрацию OP_WRITE.

Обратите внимание, что это означает, что у вас есть буфер записи на канал. По тем же причинам (read() возвращает ноль) вам также необходим буфер чтения для каждого канала. Это, в свою очередь, подразумевает объект сеанса 'канал', который содержит их обоих, и это, вероятно, прикрепление клавиши выбора канала.

0 голосов
/ 26 января 2015

OP_WRITE требуется только в тех редких случаях, когда вы хотите контролировать отставание, другими словами, когда получатель слишком медленный или отправитель слишком быстр.

...