1

サーバーとクライアントが 2 つの異なるマシンで実行されていますが、クライアントsend()はサーバーがメッセージを受信して​​いないようです。サーバーはselect()、着信接続/メッセージのソケットを監視するために採用しています。サーバーが新しい接続を受け入れると、fd_set配列が更​​新されますが、クライアントsend()メッセージにもかかわらず常に 0 が返されることがわかります。接続は TCP で、マシンは 1 つのルーターのように分離されているため、パケットがドロップされる可能性はほとんどありません。

select()おそらくsend()/クライアントからではなく、問題である可能性があると感じていsendto()ますが、問題の領域を特定する方法がわかりません。

    while(1)
{
    readset = info->read_set;   
    ready = select(info->max_fd+1, &readset, NULL, NULL, &timeout);

}

select()上記は、サーバーに無期限に実行されるスレッドがあるサーバー側のコードです。

rv = connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
printf("rv = %i\n", rv);
if (rv < 0)
{
    printf("MAIN: ERROR connect() %i:  %s\n", errno, strerror(errno));
    exit(1);
}
else
    printf("connected\n");

sleep(3);

char * somemsg = "is this working yet?\0";
rv = send(sockfd, somemsg, sizeof(somemsg), NULL);
if (rv < 0)
    printf("MAIN: ERROR send() %i:  %s\n", errno, strerror(errno));
printf("MAIN: rv is %i\n", rv);
rv = sendto(sockfd, somemsg, sizeof(somemsg), NULL, &server_address, sizeof(server_address));
if (rv < 0)
    printf("MAIN: ERROR sendto() %i:  %s\n", errno, strerror(errno));
printf("MAIN: rv is %i\n", rv);

これは、接続してメッセージを送信し、返すクライアント側です

connected
MAIN: rv is 4
MAIN: rv is 4
4

2 に答える 2

0

接続
MAIN: rv は 4
MAIN: rv は 4

特にメッセージの長さが 22 文字だったことを考えると、「rv が 4」なのは奇妙です。また、「4」は、ほとんどの 32 ビット環境でポインターのサイズになる傾向があります。何sizeof(somemsg)が得られるか見てみるべきです。私の推測では、文字列 (22) ではなく、ポインター (4) のサイズを示していると思います。

読み取りセットはどこで更新していますか? fd_set私の知る限り、構造/タイプの実装の詳細は、BSD ソケット インターフェイスの一部ではありません。ご存知のように、それはどこかへのポインターである可能性があり、システムはクライアントのソケットを最初に「準備ができていない」ときに元のセットから削除し、二度とチェックしない可能性があります。fd_setを安全かつ移植可能に更新する唯一の方法は、FD_*マクロを使用することです。

ちなみに、\0文字列の末尾に末尾は必要ありません。C はそれを文字列リテラルに追加します。

于 2010-04-17T20:31:54.147 に答える
0

fd_set readset私が問題だと思っていたものではなく、に何か問題がありました。私の注意を引いてくれたqrdlへのPROPS。

于 2010-04-17T20:46:09.390 に答える