I’ve just started using java.nio and probably used it some wrong way so I got a slight problem with it.
I’m trying to write a something like a Port Forwarder that can modify the traffic that passes through it using various additional modules.
Here is how I’m doing it:
-
ConnectionManager – a thread that
has it’s own Selector that is
registered to OP_ACCEPT on
ServerSocketChannel. Whenever it
selects anything – it creates a
ConnectionProcessor object that
manages the connection. -
ConnectionProcessor – a thread
that opens SocketChannel to
predefined forward point (where to
send the packets from the newly
connected client). Then it opens
it’s own Selector and registers it
to client’s SocketChannel’s OP_READ
and server’s SocketChannel’s
OP_READ.
Then the processor goes into infinite loop selecting data from selector and forwarding it appropriately. To determine where to send data it compares SelectionKey.channel() to clientChannel and serverChannel.
Selection in ConnectionProcessor is made with timeout of 5 seconds (select(5000)) – to handle timeouts. When select times out – it tries to read from both channels to get an exception or -1 result.
Now here are my questions/problems:
- Is it right to use key.cancel()
after processing the key? Most
examples I’ve seen in the internet
simply remove the key from
selectedKeys() list. key.cancel()
seems to be much better approach. -
Is it right to have several
selectors that basically use the
same ServerSocketChannel? Or should I always use single Selector and pass selected keys
to appropriate Managers? What I
mean is that if 3 clients connect
simultaneously then this is what
will happen:a) Manager creates Processor.
Processor opens client channel.
Processor registers it’s own
selector to the client channel. b)
repetition of (a) c) repetition of
(a) - For some reason, after even one client connects to my forwarder – it won’t process
messages faster than 5000msec timeout. It starts selecting, locks for 5 seconds, then go
to second iteration and fetches me 5-6 messages that I received during previous timeout.
Should I blame (1), (2), or some other reason? - Is there any manual on how this all nio stuff works internally? I’m kind of a person that understands how to use things only after I fully understand the mechanics underneath. Reading API does not help as it is written for people who already know the proper way of using nio.
Thanks for reading my whole question and thanks in advance for any help.
No. Just remove the key from the selected set. Usually this is done via iterator.remove(). If you cancel they key it will never be selected again.
It’s pointless. You don’t need the second selector, or the extra thread either. That’s what NIO is for. You can handle it all with the original selector within the original thread.
It’s probably caused by strange code. Redo it as above and see if it still happens. If so, post some code here.
You would need to read the Berkeley Sockets API or a good book such as Stevens, Unix Network Programming, or mine 😉