0

簡単な質問がいくつかあります。クライアントサーバーアプリケーションとデータがネットワーク上で送信されています。

データを回復して適切に処理できるようにしたいと思います。

struct T1
{
   int id;
   int foo;
};

struct T2
{
  int id;
  char foo;
  int bar;
};

これらの構造を見てみましょう。これらは、T1またはT2のいずれかが続くかどうかを示すintが前に付いたネットワーク上で送信されます。クライアントが私にT1を送信し、次にT2を送信した場合、asio :: ip :: tcp :: socket.async_read()を使用して完全な構造を読み取ることができるという保証がありますか?単一の構造体を処理するハンドラーを設定したいのですが、単一のasync_read()ですべてを読み取ることができない場合はどうなりますか?

非同期操作は、次のいずれかの条件が満たされるまで続行されます。

  • 提供されたバッファがいっぱいです。つまり、転送されるバイト数は、バッファサイズの合計に等しくなります。
  • エラーが発生しました。

読み取れないデータは破棄されますか?別のasync_readをトリガーしますか?そして、クライアントがID +構造を順番に送信した場合、async_readは1つのID +構造のみを取得することが保証されていますか?それとも、OSが物事を最適化し、両方を同じパケに入れることができますか?お気づきかもしれませんが、私は少し混乱しています。サーバー/クライアントアプリケーションを設計するときに正しい決定を下したいと思います。助けていただければ幸いです。

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

4

1 に答える 1

1

編集:間違いを指摘してくれた@timoに感謝します。async_readは、構造体全体が読み取られるまで完了しないため、ループする必要はありません。そうでなければ、私の答えは同じです。TCPプロトコルがどのようにデータを分割または合体するかに関係なく、何も失われません。

TCPバッファーに入力バッファーを満たすのに十分なデータがない場合、読み取りは使用可能なものをすべてフェッチし、フェッチされたバイト数を報告します。次に何が起こるかはあなた次第です。フェッチされたバイトに、続行したくないと判断するのに十分なデータがある可能性があるため、asioは想定を行いません。完全な構造を構成するのに十分なバイトを読み取っていない場合は、さらにasync_readを開始し、十分なバイトが得られるか何かがなくなるまでプロセスを繰り返します。

「すべてが読めない」とはどういう意味かわかりません。2つの考えられる意味が思い浮かびます。

  1. 読み取ることができるデータの量は、構造体を埋めません。この場合、別のread_asyncを実行して、さらにデータが到着するのを待ちます。
  2. 構造体は、到着したすべてのデータを吸収するわけではありません。TCPスタックは、読み取りに取り掛かるまで、未読み取りのデータを単純にバッファリングします。
于 2010-11-25T01:29:06.067 に答える