blocking sockets

A socket is in blocking mode when an I/O call waits for an event to complete. If the blocking mode is set for a socket, the calling program is suspended until the expected event completes.
If nonblocking is set by the FCNTL() or IOCTL() calls, the calling program continues even though the I/O call might not have completed. If the I/O call could not be completed, it returns with ERRNO EWOULDBLOCK. (The calling program should use SELECT() to test for completion of any socket call returning an EWOULDBLOCK.)
Note: The default mode is blocking.
If data is not available to the socket, and the socket is in blocking and synchronous modes, the READ call blocks the caller until data arrives.
All IBM® TCP/IP Services socket APIs support nonblocking socket calls. Some APIs, in addition to nonblocking calls, support asynchronous socket calls.
Blocking
The default mode of socket calls is blocking. A blocking call does not return to your program until the event you requested has been completed. For example, if you issue a blocking recvfrom() call, the call does not return to your program until data is available from the other socket application. A blocking accept() call does not return to your program until a client connects to your socket program.
Nonblocking
Change a socket to nonblocking mode using the ioctl() call that specifies command FIONBIO and a fullword (four byte) argument with a nonzero binary value. Any succeeding socket calls against the involved socket descriptor are nonblocking calls.
Alternatively, use the fcntl() call using the F_SETFL command and FNDELAY as an argument.
Nonblocking calls return to your program immediately to reveal whether the requested service was completed. An error number may mean that your call would have blocked had it been a blocking call.
If the call was, for example, a recv() call, your program might have implemented its own wait logic and reissued the nonblocking recv() call at a later time. By using this technique, your program might have implemented its own timeout rules and closed the socket, failing receipt of data from the partner program, within an application-determined period of time.
A new ioctl() call can be used to change the socket from nonblocking to blocking mode using command FIONBIO and a fullword argument of value 0 (F'0').
Asynchronous
Like nonblocking calls, asynchronous calls return control to your program immediately. But in this case, there is no need to reissue the call. Asynchronous calls are available with the macro API. For more information, see Task management and asynchronous function processing.
Table 1 lists the actions taken by the socket programming interface.
Table 1. Socket programming interface actions
Call typeSocket stateblockingNonblocking
Types of read() callsInput is availableImmediate returnImmediate return
No input is availableWait for inputImmediate return with EWOULDBLOCK error number (select() exception: READ)
Types of write() callsOutput buffers availableImmediate returnImmediate return
No output buffers availableWait for output buffersImmediate return with EWOULDBLOCK error number (select() exception: WRITE)
accept() callNew connectionImmediate returnImmediate return
No connections queuedWait for new connectionImmediate return with EWOULDBLOCK error number (select() exception: READ)
connect() call WaitImmediate return with EINPROGRESS error number (select() exception: WRITE)
Test pending activity on a number of sockets in a synchronous program by using the select() call. Pass the list of socket descriptors that you want to test for activity to the select() call; specify by socket descriptor the following type of activity you want test to find:
  • Pending data to read
  • Ready for new write
  • Any exception condition
When you use select() call logic, you do not issue any socket call on a given socket until the select() call tells you that something has happened on that socket; for example, data has arrived and is ready to be read by a read() call. By using the select() call, you do not issue a blocking call until you know that the call cannot block.
The select() call can itself be blocking, nonblocking, or, for the macro API, asynchronous. If the call is blocking and none of the socket descriptors included in the list passed to the select() call have had any activity, the call does not return to your program until one of them has activity, or until the timer value passed on the select() call expires.
The select() call and selectex() call are available. The difference between select() and selectex() calls is that selectex() call allows you to include nonsocket related events in the list of events that can trigger the selectex() call to complete. You do so by passing one or more MVS™ event control blocks (ECBs) on the selectex() call. If there is activity on any of the sockets included in the select list, if the specified timer expires, or if one of the external events completes, the selectex() call returns to your program.
Typically, a server program waits for socket activity or an operator command to shut it down. By using the selectex() call, a shutdown ECB can be included in the list of events to be monitored for activity.