Re: java socket i/o with callback/non-blocking



Shane Wealti wrote:

I have the O'Reilly Book Java NIO (with the mouse on it) and I'm trying
to figure out how to do non-blocking socket i/o.  Basically I want to
have some subroutine to be called whenever there is data available to
read on a socket object without having to poll it.  I'm having trouble
understanding how to do this in Java and the NIO book isn't really
helpful in that regard.  Right now the way I have my program written is
that I spawn a separate thread that has a while loop that checks the
socket for data and then goes to sleep for a while but that doesn't
seem like a very efficient implementation.  I'm having trouble finding
much information on NIO, especially tutorials and code samples that
deal with this.

The NIO mechanism for waiting on data without polling is the Selector. You obtain a new instance via Selector.open(), register your SocketChannel with it via the SocketChannel's register() method (specifying SelectionKey.OP_READ for its interest operations), then invoke one of the Selector's select() methods. When the method returns, you can query its selected keys set to determine which channels are ready for which operations, and do whatever you want to with the results. Typically you would put all this in a loop.


Now, all that may be dramatic overkill if you only have one channel to worry about. You still need to run it in its own thread (or at least, it's much simpler to do so), and all it really saves you is guessing at how long to wait for data. Selectors are really intended for handling multiple channels with a single thread. Note also that the technique described is blocking, not non-blocking, as indeed is the technique you described even if the channel is in non-blocking mode. You can use a Selector in a non-blocking way (see Selector.selectNow()), but I don't yet see how that would help you in your particular situation.

For just one socket, you are probably much better off to dump all the NIO stuff, and simply use blocking I/O in its own thread. (Even with multiple sockets this is often a viable approach, with one thread per socket.) What you are doing now is an inefficient simulation of that, and the Selector-based scheme for a single channel is a somewhat less inefficient simulation of it. Non-blocking I/O sounds good, but it leaves you with questions about what the thread is to do when it's not performing I/O and how to schedule the I/O attempts so as to not create an unnecessary dataflow bottleneck. Naive uses may needlessly spin, consuming CPU cycles that could have been devoted to more productive purposes.

--
John Bollinger
jobollin@xxxxxxxxxxx
.



Relevant Pages

  • Re: How do you kill a completely locked up thread?
    ... The one way to cancel pending I/O on a socket and unwedge ... // Call BeginInvoke on delegate. ... // Note on last two parameters of Delegate BeginInvoke Method: ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: How do you kill a completly locked up thread?
    ... This seems to be the only C# method I know of to kill a thread. ... For one thing, you can kill off the thread corresponding to the Thread object, but this is not guaranteed to be the thread doing the actual blocking I/O, it might just be waiting on another thread. ... When the thread is doing this connect (it will happen with even a simple TCP/IP socket connect) issue a Thread.Abortfrom another thread and you will see that the ThreadAbortException will NOT be thrown until the Connect call returns. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: http webserver using select()
    ... "Binding" file descriptor with open file to accepted socket descriptor ... fds for each connection. ... generate socket fd via socket-> listening socket ... For other 1 bits in fd_set, handle I/O ...
    (comp.unix.programmer)
  • Re: [6.x] problem with AIO, non-blocking sockets on freebSD and IE7 on windows.
    ... Yes, Blame Microsoft, but we are breaking the TCP spec, not them. ... A TCP socket isn't the same thing as a named pape or FIFO. ... Using non-blocking I/O does not mean one can suddenly shortcut the FINWAIT-1 and FINWAIT-2 states before going into TIME_WAIT, nor the 2 * MSL timeout before the TCP control block is allowed to go away. ... Otherwise, you might end up sending a RST to a dup'ed packet like a stray ACK, which seems to be almost exactly the problem at hand. ...
    (freebsd-net)
  • Trying to learn Non-Blocking sockets on Solaris 8, please help! ready to fork() it.
    ... how to setup a non-blocking socket. ... I've found limited information on ... opening a socket and using the ioctlto set it to non-blocking ... Whats the differance between fcntl and ioctl? ...
    (comp.unix.programmer)