Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Errno: 11, Resource Temporarily Unavailable

Tags:

c

sockets

udp

I am using c sockets to implement a reliable UDP protocol. I am using the following code to set a timeout on a socket in which I'm waiting for an acknowledgement. I am not sure why I am getting errno 11, resource temporarily unavailable.

        //set timer for recv_socket
        struct timeval tv;
        tv.tv_usec = TIMEOUT_MS;

        if(setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0){
            printf("Error setting the socket timeout.\n");
        }

        int recv_msg_len;
        if(recv_msg_len = recvfrom(rcv_sock, ackBuffer,sizeof(ackBuffer), 0,
               (struct sockaddr *) &servAddr2, &fromSize) < 0){
            //timeout reached
            printf("Error Reporting: %d : %s\n", errno, strerror(errno));
            num_timeouts++;
        }

I have also tried the select method that was mentioned in the comments. I have the following code inside a loop, but the recvfrom never times out.

        fd_set set;
        FD_ZERO(&set);      /* empties the set */
        FD_CLR(rcv_sock,&set);    /* removes FD from the set */
        FD_SET(rcv_sock,&set);    /* adds FD to the set */

        if(select(rcv_sock + 1, &set, NULL, NULL, &tv) < 0){
            printf("\nError Reporting: %d : %s\n\n", errno, strerror(errno));
            return -1;
        }


        if(!FD_ISSET(rcv_sock,&set)){   /* true if FD is in the set */
            printf("socket is not set properly.\n");
        }
like image 406
rharrison33 Avatar asked Nov 25 '12 19:11

rharrison33


2 Answers

When calling recvfrom() on a blocking socket and a time out had been set using setsockopt() it is normal to get the error EAGAIN (11) in case the call to recvfrom() timed out (that is: no data was received in the time period specified as time out).

Verbatim from man recvfrom:

RETURN VALUE

...

ERRORS

... .

EAGAIN or EWOULDBLOCK The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received. ...

To get around this: Just call recvfrom () again ... ;-)

like image 60
alk Avatar answered Nov 03 '22 21:11

alk


For me, the problem was due to ipV6 packets arriving on a UDP socket bound to a particular port. These were triggering the select() but when I tried to read them using recvfrom() the call returned "Resource temporarily unavailable". I don't need IPV6 for my application so I simply disabled it via sysctl.conf. Problem now gone away!

like image 1
user3704779 Avatar answered Nov 03 '22 19:11

user3704779