3

.net で tcp ストリームを使用する方法について少し混乱しています。今、書きたいときは、40バイトと言って、それをメモリストリームに書き込んでから、ToArray()を呼び出し、メモリストリームをネットワークストリーム+フラッシュに書き込みます。

サーバー側では Read(buf, 0, len) を使用し、長さが期待どおりかどうかを確認します。私は愚かな方法でこれをやっていますか?必要なだけ小さなバイトを書き込んで、読み取りの準備ができたらフラッシュすることはできますか?

Read() を実行すると、常に期待どおりの長さが得られますか? (アプリが正しく、エラーが発生していないと仮定します) サイズが揃うまでブロックされますか? 読み取りをループしてバッファを構築する必要はありませんか? 10k 以上のような大きなサイズを期待しているとしましょう。その場合、バッファを構築する必要がありますか?

4

3 に答える 3

2

以前の両方の回答があなたにそれを伝えていることは知っていますが、それらを繰り返して私のものを追加します。後続の送信の間に十分な時間があれば、期待どおりに機能し、実際に機能すると信じるようになるかもしれませんその方法。しかし、そうではありません。

TCP は、一方の端にコップ一杯の水を入れている WATER PIPE として簡単に視覚化できます。新しいコップ一杯の水を追加しても、そのサイズについては何もわかりません。パイプに水を追加するだけです.

そのため、独自の「メッセージング」または「パケット化」をストリームに実装する必要があります。

しかし、それはそれほど悪くはありません。ストリームはロバストなので、データに長さのプレフィックスを付けると、それを機能させることができます-受信側である種の「パケット収集メカニズム」を作成するだけです-取得するまで部分的なパケットデータを保持するバッファーをいくつか用意しますあなたが必要とするすべて。

編集:

質問に答えるには:

  • Flush()ここでは無関係です。
  • 期待するサイズは得られません。0からトランジットに残っているものまでの範囲で何でも取得します
  • サイズの準備が整うまでブロックされません。それは可能な限りあなたを手に入れます(0は可能性です)-その動作は変更できると思いますが、Write()相手側にバイト数nを持つものは何もありません
  • バッファを構築する必要があります
  • はい、データの長さにプレフィックスを付けて、手動でバッファーを作成する必要があります

ここで、バッファを読み取る方法についていくつかのアイデアがあります: .NET は、X バイトが使用可能になるまでソケットの読み取りをブロックしますか?

于 2012-07-13T22:31:45.870 に答える
0

Windowsソケットには、内部同期メカニズムはありません。したがって、取得したバイトの部分が最終的なものであり、他のデータが予期されていないことを確認することはできません。常に取得したすべてのデータを追跡し、いつ取得を停止できるかを決定する必要があります。

于 2012-07-13T22:23:16.160 に答える
0

ストリームが使い果たされた場合、読み取りサイズは0になり、少なくとも1からバッファのサイズまでになります。その範囲内の任意のサイズにすることができます。一般的なサイズは、ネットワークMTUの倍数(約1452バイト)です。

バッファを希望のサイズまで徐々に満たすには、ロジックを自分で実装する必要があります。

送信されたチャンクサイズと受信されたチャンクサイズの間に関係はありません。

ファイルシステムは基本的に、ファイルの最後を除いて、要求されたバッファを常に完全にいっぱいにする唯一の一般的なStream実装です。他のStream実装は、その保証を行いません。

これらはすべて、パフォーマンスのために行われた設計上の選択です。

于 2012-07-13T22:26:31.453 に答える