Errno: 11, Ресурс временно недоступен

Я использую c сокеты для реализации надежного протокола UDP. Я использую следующий код, чтобы установить тайм-аут в сокете, в котором я жду подтверждения. Я не уверен, почему я получаю errno 11, ресурс временно недоступен.

        //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++;
        }

Я также попробовал метод select, упомянутый в комментариях. У меня есть следующий код внутри цикла, но recvfrom никогда не истекает.

        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");
        }

Ответ 1

При вызове recvfrom() на блокирующем сокете и времени ожидания, установленном с помощью setsockopt(), нормально получить ошибку EAGAIN (11) в случае истечения времени ожидания вызова recvfrom() (то есть: в период времени указан как тайм-аут).

Дословно из man recvfrom:

RETURN VALUE

...

ERRORS

... .

EAGAIN или EWOULDBLOCK               Сокет помечается как неблокирующий, и операция приема будет блокироваться, или установлен тайм-аут приема, и истекло время ожидания до получения данных....

Чтобы обойти это: просто позвоните recvfrom () снова... ;-)

Ответ 2

Для меня проблема связана с тем, что пакеты ipV6, входящие в UDP-сокет, привязаны к определенному порту. Они запускали select(), но когда я попытался их прочитать, используя recvfrom(), вызванный вызов "Ресурс временно недоступен". Мне не нужен IPV6 для моего приложения, поэтому я просто отключил его через sysctl.conf. Теперь проблема исчезла!