TServerSocket
受信バッファにすべてのデータが含まれているかどうかを判断することはできますか?
3 に答える
それがプロトコルの場合です。
- 定義済みの終了トークンにすることができます。例: HTTP の CR LF CR LF
- リクエストの長さを含むヘッダー。
定義上は終わりがないため、OnRead が読み取りを終了したかどうかを判断する方法はありません。これは、特別な情報なしで単純にバイナリ データを送信してはならないことを意味します。たとえば、最初にバイト数を送信し (たとえば、4 バイトの符号なし整数として)、次に送信するバイト数を送信できます。
受信者側では、最初に 4 バイトを読み取り、これで期待できるバイト数がわかります。
サーバー上のクライアントからデータを読み取る場合は、バッファー文字列 (クライアント ソケットごと) とその文字列を解析するループを使用するのが一般的な方法です。たとえば、各サーバー/クライアント ソケットをラップするオブジェクトを作成するとします。このオブジェクトで、 という文字列を作成しますBuffer
。クライアントからデータを受け取るたびに、この文字列の末尾に新しいデータを追加します。次に、別のプロセス (スレッド) がこの文字列を解析し、完全なパケットをチェックします。ただし、パケット サイズを読み取る方法はすべてユーザー次第です。
サーバーが送信された順序でデータを受信したときにイベントをトリガーするという保証はありません。クライアントは 4 つのデータ パケットをサーバーに送信し、サーバーはそのすべてに対して 1 つのイベントのみをトリガーするか、クライアントが 1 つのデータ パケットを送信し、サーバーはそのデータの一部に対して 2 つのイベントをトリガーします。ソケット通信の性質に応じて、完全を期すために入ってくるデータを継続的に読み取る責任があります。
アルザイマーの答えは、あなたがする必要があることです。1 つの完全なパケットが次のような文字列であるとします。
This is some string.
このような文字列を解析する場合、区切り記号を使用するのは危険です。代わりに、その文字列のサイズを取得し、そのサイズとデータの間に区切り記号を 1 つだけ付けて、パケットの前に置きます。上記の文字列は 20 文字なので、実際のパケットは次のようになります。
20:This is some string.
...ここで、コロン (:) は、サイズとデータの間の区切り記号です。まず、区切り記号が存在することを確認します。もしそうなら、それまでのすべてをコピーします。有効な数値である場合、バッファからその数の文字を読み取る必要があることを意味します。次に、バッファに十分な量のデータがあるかどうかを確認します。その場合は、バッファからそのデータを取得します。必要な場合にのみバッファからデータを削除することを忘れないでください。必要に応じて、より詳細なコード例を提供できます。