Re: NIO



["Remon van Vliet" <remon@xxxxxxxxxxxx>]
|
| 1) establish a connection using a non-blocking socket connect()
| 2) wait for finishConnect() to return true

the proper way to do proper non-blocking connect is to issue the
connect, register interest in OP_CONNECT with a selector, perform
select and then call finishConnect() once the connection has
OP_CONNECT in its ready set.

looping around finishConnect() until it returns true is pointless and
consumes unecessary CPU; it is better to connect the socket while in
blocking mode and then change it to nonblocking once the connect() has
completed.

BUT!

beware of nonblocking connect() with NIO though: the decision to
implement OP_CONNECT as a separate operation category seems to have
lead to some errors in 1.4 implementations of NIO. this is supposedly
fixed in 1.5 (I have not verified that this is so, but Sun's bug
database says the issue has been addressed in Tiger).

the reason is probably that in the underlying implementation
OP_CONNECT is implemented by way of OP_WRITE -- ie. an unconnected
socket in connecting state that becomes writable has finished its
connect so the OP_CONNECT state doesn't really "exist" (at least on
platforms where select() is used). a common error mode for this bug is
that this can lead to a Selector never blocking on select() again,
which of course, defeats its entire purpose and leads to CPU-hogging
busy-wait.

my recommendation is therefore that for code that might run on 1.4
JVMs, *don't* do asynchronous/nonblocking connects; change the mode of
the connection after the connect is completed.


after all, that *is* the net effect of what you are describing -- just
without the busy-wait.

| 3) At this point you can send data, do so once the OP_WRITE key is selected
| after a select() call
| 4) Write all data (in a secure way, meaning keep track of what you send and
| make sure you send it all)
| 5) Once this is done you can close the connection
|
| Now, be sure you actually need non-blocking sockets to begin with. For a
| limited number of connection blocking sockets are much easier to work with.
| Use non-blocking sockets only when you wish to manage multiple connection
| with one thread.

I'd actually recommend gaining some experience with what the NIO is
(sort of) modeled from first. I have seen a lot of rather experienced
Java programmers trying to wrap their heads around NIO and most of the
time the problem is that they have no experience in writing
applications that perform connection multiplexing in C on UNIX.

write a single-threaded program in C which handles multiple
connections in parallel using select() or poll(). for instance a
simple download program which can take a list of URLs and download
them in parallel from N servers simultaneously.

NIO has its own set of quirks and bugs which you need to learn as
well, but you won't come very far until you have a proper
understanding of the underlying concepts, OS apis and techniques.

also, read the second edition of W Richard Stevens "Unix Network
Programming". even if you are a Java programmer and you could care
less about UNIX this is still pretty much a "must read" for anyone
wanting to understand network programming.

-Bjørn
.



Relevant Pages

  • Re: Java NIO Strategy
    ... have no oppurtunity to close the connection and no oppurtunity to kill ... Any serious NIO application should use a timed select and have an idle process that is run when the select times out with no ready keys. ... The idle process should scan the registered key set for channels which haven't done anything for a while, using last-read/last-write timers held in the Session attachment, and take application action to close these connections. ...
    (comp.lang.java.programmer)
  • Re: Establishing Socket Connection to a slow or busy server
    ... The big problem using the standard Socket classes up until jdk 1.3 is ... jdk 1.4 added the nio classes which perform much ... the connection, but then it is no longer asynchronous/non-blocking. ... See my post on this group about nio and timeouts. ...
    (comp.lang.java.programmer)
  • Re: how do you prevent a channel from being closed on a "connection refused" error with finishConnec
    ... get a "connection refused" IOException. ... defeats the purpose of using a selector on a channel in the first ... As Gordon said in your other thread on the same topic, finishConnect() should be called after OP_CONNECT has fired in a Selector. ...
    (comp.lang.java.programmer)
  • Re: Question about non-blocking NIO and Selection Keys
    ... I thought NIO was for reading several connections to the same socket, using one thread per socket instead of the traditional one thread per connection. ...
    (comp.lang.java.programmer)