5

sendto に問題があります。

recvfrom で UPD パケットを受信し、sendto を使用して送信者に返信する受信者がいます。

残念ながら、errno 11 (リソースが一時的に利用できません) が表示されます。ソケットを2つ使用しています。

最初のパケットは実際に送信されますが、その後のパケットは送信されません:

sendto :: 成功

エラー: 0。

sendto :: リソースが一時的に利用できません

エラー: 11.

sendto :: リソースが一時的に利用できません

...

これは私のコードの抜粋です:

    int sockfd, sockSend;

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
            perror("socket");

    if ((sockSend = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
            perror("socket");

    if (fcntl(sockfd, F_SETOWN, getpid()) < 0) {
            perror("fcntl"); 
    }
    if (fcntl(sockfd, F_SETFL, O_RDONLY | O_NONBLOCK | FASYNC) < 0) {
            perror("fcntl"); 
    } 

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr))
                    < 0)
            perror("bind");

そして、SIGIO ハンドラーで:

    len = sizeof(recv_addr);
    char buffer[payload];
    bzero(buffer, payload);
    n = recvfrom(sockfd, buffer, payload, MSG_DONTWAIT, (struct sockaddr *)&recv_addr, &len);

    while (n > 0) {

                            sprintf(response, "%d\n%d\n%d\n", items, target_buf, pb_sp);          
                            sendto(sockSend, response, strlen(response), 0, (struct sockaddr *) &recv_addr, sizeof(recv_addr));
                            // sleep(1);

                            perror("sendto :");
                            printf("error: %d.\n", errno);

     }

この問題は、ポートがまだホットで、再利用する前に待つ必要があるために発生する可能性がありますか? ポートを変更しようとしましたが、役に立ちませんでした。

更新: sleep(1) がコメントアウトされている場合、パケットは実際に送信されます!

どうもありがとうございました。

4

2 に答える 2

11

あなたが得ているエラー:

EAGAIN または EWOULDBLOCK: ソケットは非ブロッキングとマークされており、要求された操作はブロックされます。POSIX.1-2001 では、この場合にいずれかのエラーが返されることを許可しており、これらの定数が同じ値である必要はないため、移植可能なアプリケーションは両方の可能性をチェックする必要があります。

ソケットをノンブロッキング (O_NONBLOCK) に設定します。ソケットはまだ前のメッセージの送信でビジー状態です。最初の送信が完了するまで、次の送信はできません。そのため、睡眠が役立ちました。

ノンブロッキングに設定しないでください。または、selectできると言われたら再試行してください。

于 2011-04-21T00:09:45.140 に答える
0

ソケットをノンブロッキングに設定する必要がある場合は、以下を使用して安全に (そして唯一?) 行うことができますselect

select()pselect()を使用すると、プログラムは複数のファイル記述子を監視し、1 つまたは複数のファイル記述子が何らかのクラスの I/O 操作 (たとえば、入力可能) に対して「準備完了」になるまで待機できます。ブロックせずに対応する I/O 操作 (read(2) など) を実行できる場合、ファイル記述子は準備完了と見なされます。

于 2015-08-14T18:30:19.323 に答える