["Remon van Vliet" <
[email protected]>]
|
| 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