web-dev-qa-db-ja.com

エラーノ:11、一時的に利用できないリソース

私は信頼できるUDPプロトコルを実装するためにcソケットを使用しています。次のコードを使用して、確認を待っているソケットにタイムアウトを設定しています。 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++;
        }

また、コメントに記載されている選択方法も試しました。ループ内に次のコードがありますが、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");
        }
12
rharrison33

ブロッキングソケットでrecvfrom()を呼び出し、setsockopt()を使用してタイムアウトを設定した場合、EAGAIN (11)の呼び出しの場合にエラーrecvfrom()を取得するのは正常ですタイムアウト(つまり、タイムアウトとして指定された期間にデータが受信されなかった)。

man recvfromからの逐語:

戻り値

...

[〜#〜]エラー[〜#〜]

..。

EAGAINまたはEWOULDBLOCKソケットは非ブロッキングとマークされ、受信操作はブロックされます、または受信タイムアウトが設定され、データが受信される前にタイムアウトが期限切れになりました。 ...

これを回避するには、もう一度recvfrom ()を呼び出します... ;-)

13
alk

私にとって、問題は特定のポートにバインドされたUDPソケットに到着するipV6パケットが原因でした。これらはselect()をトリガーしていましたが、recvfrom()を使用してそれらを読み取ろうとすると、呼び出しは「リソースが一時的に利用できません」を返しました。アプリケーションにIPV6は必要ないので、sysctl.confを使用して単純に無効にしました。問題はなくなりました!

0
user3704779