0

TCP 経由でデータを交換するクライアントとサーバー プログラムを構築していますが、操作が成功したときに、サーバーからクライアントに ACK 確認を送信するのに問題があります。クライアントからサーバーにさまざまなメンバーを含む構造体を送信することができました。サーバーは、構造体の ID を確認する整数をクライアントに送信して応答する必要があります。

server.c には次の関数があります。

int sendACK(int socket, int ack_int){

    int com_result;
    int ACK = htonl(ack_int);

    printf("\n\tSending ACK with value: %i", ack_int);

    com_result = send(socket, &ACK, sizeof(ACK), 0);

    if (com_result == -1) {
        perror("\n\t[ERROR] Send ACK");
        return 0;
    }

    return 1;

}

この関数は、次のように server.c の別の関数によって呼び出されます。

int ACK = myStruct->ID;
sendACK(socket, ACK);

したがって、ID: 2 の構造体を受信したばかりの場合、出力は次のようになります
。Sending ACK with value: 2

client.c では、次のように ACK を受け取ります。

int ACK = 0;
data_size  = sizeof(myStruct.ID);
com_result = read(client_socket, &ACK, data_size);
ACK = ntohl(ACK);

if (com_result == -1) {
    perror("\n\t[ERROR] Read");
} else {
    printf("\n\tRecieved %i of %i bytes", com_result, data_size);
    if (ACK != myStruct.ID) {
        printf("\n\t[ERROR] Invalid ACK (%i).", ACK);
    }
}

しかし、 ACKは常に値 1 で受信されるため、クライアントからの出力は次のようになります

整数が2の値で受信されないのはなぜですか?どうすればこれを修正できますか?

4

5 に答える 5

3

これはおそらく問題ではありませんが、以下の client.c スニペットの 2 行目は sizeof(ACK) である必要があると思います。

int ACK = 0;
data_size  = sizeof(ACK); // was: sizeof(myStruct.ID);
com_result = read(client_socket, &ACK, data_size);
ACK = ntohl(ACK);

また、データフローによっては、実際に正しく読み取っていて、ACK が以前に送信したパケットからの応答である可能性はありますか?

于 2009-11-19T11:45:28.990 に答える
1

このように値全体を送信しないでください。シリアル化にもっと注意を払う必要があります。sizeof (int)たとえば、送信側マシンと受信側マシンの が異なる場合、これは失敗する可能性があります。この場合、誤ったバイト数を読み取ることになります。

より注意して、一度に 1 バイトずつフィールドをシリアライズすることをお勧めします。

于 2009-11-19T10:59:11.210 に答える
1

デバッグするには、 wiresharkを使用できます。Wiresharkを実行し、必要なポートをリッスンするようにオプションを設定します。ネットワークを介してパケット内で実際に何が送信されたかがわかります。これにより、問題がサーバーにあるのか、クライアントにあるのか、またはその両方にあるのかを理解できます。

于 2009-11-19T11:02:31.603 に答える
0

上に貼り付けたコードに問題があることはわかりません。Wireshark または別のソケット トレース プログラムを入手して、ワイヤ上のビットを調べることをお勧めします。

于 2009-11-19T11:04:20.930 に答える
0

メインの送信者/受信者コードが正しい量のデータを処理しているかどうかを確認します。

送信者が 20 バイトの後に 4 バイトの ACK を送信し、受信者が ACK を読み取ろうとする前に 16 バイトしか読み取らない場合、この種の問題が発生する可能性があります。

可変長データを送信している場合 (つまり、bytecount プレフィックスを使用して)、送信されているバイト数に、バイト数を送信するために必要な追加のバイトが実際に含まれているかどうかについてのよくある混乱...

于 2009-11-19T12:05:46.157 に答える