Hi all, How does non-blocking sockets work internally? In a blocking socket, server is listening on a port and when clients contact server, a dedicated ClientScoket is created to handle each specific client to pass messages back and forth. Is essentially the same thing happen but under the hood in case of non-blocking sockets? And if not, how does server keep track of the each client's socket? Thanks, Payam.
Also, in the blocking socket version, a new thread is spawn to handle each client's request. If I remember corrrectly, in non-blocking socket we do not have to do that. How is that possible? Is it going to spawn a new thread behind the scenes or is it going to use some sort of timesharing to handle client's requests? Thanks, Payam.
Sockets represent network connections maintained by the operating system. Java Socket objects are abstractions within the JVM that provide a one-to-one mapping - each Socket object encapsulates an OS network connection. In the traditional Java socket implementation, Socket objects are always blocking. That is, when attempting to read data from a socket, if no data is available on the corresponding network connection then the thread attempting the read is put to sleep until some data arrives. This is fine if the only thing you're doing is processing data from that one socket. Most operating systems provide for sockets being placed into non-blocking mode. In non-blocking, a read will either return some data (if available) or return nothing - but it always returns immediately. This means the invoking thread will never get stuck. One thread can sequentially poll any number of sockets looking for those with data available. Unfortunately, the Java abstraction of a socket, prior to NIO, did not allow you to request that the socket be placed in non-blocking mode - even if that's supported by the OS. Java never automatically created a thread per socket. This is a programming technique to manage multiple sockets necessitated by the limitations I just described. Because a thread would be forced to wait if it attempted a read on an empty socket, the only way to manage multiple sockets was to dedicate a thread to each. As data became available on a given socket, its thread would wakeup and complete the read. This thread-per-socket scheme is not scalable for several reasons. First, the JVM thread scheduler becomes stressed as the number of threads grows large. This slows everything down because all those sleeping threads must be managed. It also incurs a lot of context switches as control flip-flops among the threads. Also, all these threads usually must coordinate concurrent access to common objects. The locking overhead becomes signficant and the potential for thread races grows. Plus it's complex and error prone. So no, threads are not created behind the scenes with NIO non-blocking sockets. Quite the opposite, the need for spawning a thread per socket is eliminated. This allows a single thread to service many sockets without being concerned that it will get stuck if one of them has no data to read. Additionally, NIO includes a new object named Selector which can tell you which of a group of sockets have data to read - eliminating the need to poll each one to check for data. I hope that sheds a little light on the subject. [ April 17, 2003: Message edited by: Ron Hitchens ]