1

目盛りベースの間隔で動作するバークレー C ソケットを使用して、C/C++ でリアルタイム ネットワーク システムをプログラミングしています。ティックごとに、クライアント プログラムは recvfrom() を使用してソケットからデータを読み取ります。

問題は、サーバーがデータを送信しなかった場合、クライアントはソケットで送信された最後のデータを読み取ることです。

たとえば、クライアント (疑似コード)

while (true)
{
   if (time_to_update())
   {
      int n = recvfrom(data,...);
      printf("%s",data);
   }
}

そしてサーバー:

int main()
{
   int m = recvfrom(data,...);
   int n = sendto(...,"hello");
}

その後、クライアントは「こんにちは」を印刷し続けますが、私は一度だけ印刷する必要があります。

これは、この質問recvfrom re-reading data on socketに似て いますが、答えがよくわかりません。問題をより一般的に解決しているようです。

データはネットワードカードのバッファに保存されていると思いますが、その場合、1回の読み取り後にバッファをクリアする方法はありますか? 私が考えている別の方法は、パケットに番号を付けて新しいものだけを読み取ることですが、すべてのタイプは有限であるため、よりクリーンな方法があることを願っています。

クライアントが受信したデータを一度だけ読み取るようにするにはどうすればよいですか?

4

2 に答える 2

4
printf("%s",data);

通常の問題。エラーをテストしていません。ストリームの終わりをテストしていません。長さは使いません。次のようにする必要があります。

if (n < 0)
{
    perror("recv");  // or better
    break;
}
else if (n == 0)
    break; // peer has disconnected 
else
    printf("%.*s", n, data);

これらのことをチェックしないと、永久にスピンし、発生したときにガベージを出力します。

データはネットワードカードのバッファに保存されていると思います

いいえ。

その場合、1回の読み取り後にバッファをクリアする方法があります

読めばクリア。あなたの問題は別の場所にあります。

于 2016-05-31T12:32:27.190 に答える
3

変数の戻り値をチェックしていますmか? ゼロまたは -1 を返す可能性が非常に高く (したがって、バイトは読み取られていません)、何も変更されていないため、同じ値をdata何度も再出力し続けます。

于 2016-05-31T12:29:51.263 に答える