Sockets can be set to either blocking or nonblocking I/O mode. The FIONBIO ioctl operation is used to determine this mode. When the FIONBIO ioctl is set, the socket is marked nonblocking. If a read is tried and the desired data is not available, the socket does not wait for the data to become available, but returns immediately with the SOCEWOULDBLOCK error code.
When the FIONBIO ioctl is not set, the socket is in blocking mode. In this mode, if a read is tried and the desired data is not available, the calling process waits for the data. Similarly, when writing, if FIONBIO is set and the output queue is full, an attempt to write causes the process to return immediately with an error code of SOCEWOULDBLOCK.
An example of using the ioctl() call to help perform asynchronous (nonblocking)
socket operations is:
An Application Using the ioctl() Call
int s; int bytes_received; int dontblock; char buf[256]; int rc; ... dontblock = 1; ... rc = ioctl(s, FIONBIO, (char *) &dontblock); ... bytes_received = recv(s, buf, sizeof(buf), 0); if (bytes_received == -1) { if (sock_errno() == SOCEWOULDBLOCK) /* data is not present */ else /* error occurred */ } else /* bytes_ received indicates amount of data received in buf */
This example causes the socket s to be placed in nonblocking mode. When this socket is passed as a parameter to calls that would block, such as recv() when data is not present, it causes the call to return with an error code, and sets the error value to SOCEWOULDBLOCK. Setting the mode of the socket to be nonblocking allows an application to continue processing without becoming blocked. For a more detailed description, see ioctl().
When performing nonblocking I/O on sockets, a program must check for the SOCEWOULDBLOCK error code. This occurs when an operation would normally block, but the socket it was performed on is marked as nonblocking. The following socket calls return a SOCEWOULDBLOCK error code:
Processes using these calls should be prepared to deal with the SOCEWOULDBLOCK error code. For a nonblocking socket, the connect() call returns an SOCEINPROGRESS error code if the connection cannot be completed immediately.
If an operation such as a send operation cannot be done completely, but partial writes are permissible (for example when using a stream socket), the data that can be sent immediately is processed, and the return value indicates the amount actually sent.