开发者

Java NIO Server

开发者 https://www.devze.com 2023-03-28 03:41 出处:网络
Currently I\'m working on a Java NIO Server (single-threaded) and have encountered some problems. The server accepts incoming connections, writes initial packets (the packet contains some data that cl

Currently I'm working on a Java NIO Server (single-threaded) and have encountered some problems. The server accepts incoming connections, writes initial packets (the packet contains some data that client uses for further communication) to clients but doesn't read from them. The server tries to read only when I close the client and, of course, it returns -1.

When accepting connec开发者_运维问答tion, it's being registered under:

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

selectionKey.isReadable() returns false (should it?)

Before sending initial packet, ops are changed to:

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

After sending initial packet, ops are changed to:

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

Packet gets sent.

What could be the problem? Can it be related to client?


selectionKey.isReadable() returns false (should it?)

Certainly, until there is data to read, or end of stream.

Before sending initial packet, ops are changed to:

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

Bad idea. OP_WRITE is almost always ready, i.e. except when the socket send buffer is full, so you will just cause your Selector.select() method to spin mindlessly.

When you want to write to the channel, just write. Do that in the classic loop:

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

If count is zero, you should then register for OP_WRITE, break out of the loop, and go back to the Selector loop. If you got out of this loop without that happening, deregister OP_WRITE.

Note that this implies you have a write buffer per channel. For similar reasons (read() returning zero) you also need a read buffer per channel. That in turn implies a channel 'session' object that contains them both, and that is probably the attachment of the channel's selection key.


OP_WRITE is only needed in the rare circumstances where you want to control lagging, in other words, when the receiver is too slow or the sender is too fast.

0

精彩评论

暂无评论...
验证码 换一张
取 消