18

信頼できる 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");
        }
4

2 に答える 2

23

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

からの逐語的man recvfrom

戻り値

..。

エラー

...。

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

これを回避するには:recvfrom ()もう一度電話してください... ;-)

于 2012-11-26T11:05:29.503 に答える
1

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

于 2015-05-05T19:03:04.723 に答える