Search code examples
cfile-descriptor

Why does reading a non-blocking socket return an error status code


After successfully reading a socket set up as non blocking, the socket becomes temporarily unavailable. All data is received already with the first read call, but the error return value persists for about 5 seconds. After that read returns 0 and the socket is once more available.

Why does the socket return the error in the first place?

Set up non blocking socket:

/* Non blocking */
int flags = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, flags | O_NONBLOCK);

Read socket and print:

result = read(sockfd, response + bytes_read, RESPONSE_SIZE - bytes_read);
printf("%d | %d | %s\n", (int)result, errno, strerror(errno));
printf("%d | %d | %d | %d | %d | %d | %d | %d \n",
            EAGAIN, EWOULDBLOCK, EBADF, EFAULT, EINTR, EINVAL, EIO, EISDIR);

Which results in:

152 | 115 | Operation now in progress
11 | 11 | 9 | 14 | 4 | 22 | 5 | 21 

-1 | 11 | Resource temporarily unavailable
11 | 11 | 9 | 14 | 4 | 22 | 5 | 21 

Solution

  • If there is no data available in a non-blocking file of a FIFO or socket type, a read will fail with -1 and set errno to EWOULDBLOCK. An alias to this errno code is EAGAIN, which signals you to try again (later, after more data has been entered).

    The 0 return value from a read on a socket indicated that an end-of-file condition was meant (which means, for a socket, that a shutdown occurred).

    From read(2):

    (zero indicates end of file)

    ...

    On error, -1 is returned, and errno is set appropriately.