TCP 経由でパケットを送信すると、2 つのパケットに分割されます
質問
私はサーバークライアントモデルを使用してC#でアプリケーションを開発しています。サーバーはビットマップを含むバイト配列をクライアントに送信し、クライアントはそれを画面にロードし、「OK」をサーバーに送信し、サーバーは別の画像など。
画像バッファの長さは依存しますが、通常は 60kb から 90kb の間ですが、それは問題ではないことがわかりました。localhost を使用してクライアントとサーバーを同じコンピュータに配置すると、すべてが正常に動作します。サーバーは beginSend を実行し、クライアントは endReceive を実行して、バッファ全体が送信されます。
ただし、現在これをワイヤレス ネットワークでテストしているところ、何が起こるかというと、次のとおりです。
- サーバーが画像を送信します。
- クライアント上のコールバック関数 data_received が呼び出されますが、読み取る必要があるのは 1460 バイトのみです (MTU - なぜですか?UDP だけにあるべきではないでしょうか?)
- クライアント上のコールバック関数 data_received が再度呼び出され、残りのバッファ (1000 バイトまたは 100 キロバイト) が使用されます...
常にこのようになり、1460 バイトの最初のパケットが受信され、2 番目のパケットには残りが含まれます。
受信した両方のバイト配列を結合することでこの問題を回避できますが、これは正しくないようです。なぜこれが起こっているのかさえわかりません。ネットワーク上の何らかの制限でしょうか?では、なぜ C# はデータ全体が送信されるまで待たないのでしょうか?つまり、TCP なので、心配する必要はありませんね。
とにかく、どんな助けでも素晴らしいです!
乾杯
解決
これはTCPです - あなたは、ののストリームとしてデータを扱う必要があります。あなたは、ストリームをパケットに分割されるかを気に、またはそれについての仮定を行うべきではありません。
あなたは、データの単一の「ブロック」を受信する必要がある場合は、、確実にそれを行うための最も簡単な方法は、(例えば、32ビット値として)長さでそれをプレフィックスすることです。あなたは長さを読んで(でも、それらのバイトは<全角>ことを指摘できた。の複数のパケットに分割すること)し、その後、繰り返し読んで、あなたはすべて読んだまでは、毎回読んでどのくらいのノートを取って(同期または非同期か)データ。
他のヒント
9.2.4 の
の読み取りを持っていますアプリケーション層のプロトコルを解剖するとあなたは各TCPパケットが正確に一つのアプリケーション層メッセージが含まれていると仮定することはできません。一つのアプリケーション層メッセージは、複数のTCPパケットに分割することができます。
ジョンの答えに追加する:
int offset = 0;
int imagesize = 512;
byte[] buffer = new byte[512];
tcpChannel.Read(buffer, offset, imagesize);