1

ネットワーク経由でデータを読み取る場合、データを受信するバッファを指定します。

byte[] b = new byte[4096];
socket.Receive(b);

私が最初に考えたのは、もちろん、受信バッファーをクラスのメンバー変数として宣言して再利用することです。次の問題は、期待するすべてのデータを受信して​​いないため、データをバッファリングする必要があることです。これは、受信したバイト数を追跡​​し、オフセットを指定することで簡単に実現できます。

socket.Receive(m_ReceiveBuffer, count, m_ReceiveBuffer.Length - count);

さて、ここでの問題は、それでも十分でない場合は、バッファを拡張する必要があると推測していることです。つまり、メモリをコピーして、このバッファに受信し続ける必要があります。何かがうまくいかなかったと仮定すると、このバッファは増え続け、十分な大きさのメッセージが受信されると、システムのメモリが不足します。

これを適切に処理する方法はありますか?私が話している、単に塗りつぶし、コピー、拡大、塗りつぶし、コピー、拡大するよりも、データを受信するためのより良い方法はありますか?

4

3 に答える 3

2

チャンクで読む:

const int ChunkSize = 4096;
int bytesRead;
byte[] buffer = new byte[ChunkSize];
while ((bytesRead = socket.Receive(buffer, 0, ChunkSize, SocketFlags.None)) > 0)
{
    byte[] actualBytesRead = new byte[bytesRead];
    Buffer.BlockCopy(buffer, 0, actualBytesRead, 0, bytesRead);
    // Do something with actualBytesRead, 
    // maybe add it to a list or write it to a stream somewhere
}
于 2009-09-10T08:24:34.653 に答える
1

SYstem.Net.Sockets.Socketを開始する前に、すべての厄介なバッファーが機能し、簡単に管理できるストリームに変換するSystem.Net.Sockets.TcpClient(またはUdpClient)を使用できないことを確認しますか?

そうでない場合は、受信するデータの量が要求した量と同じである必要はないため、受信関数からの戻り値を常に確認する必要があることに注意してください。そして、メモリが不足しないようにする唯一の方法は、受け取ったものを実際に処理することです。

于 2009-09-10T08:25:07.510 に答える
0

まず、コードをデータの受信と処理に分けます。受信バッファは、コードがデータを処理領域にコピーする機会を得るまで、データを保持する必要があります。処理領域は、何か有用なことを行うのに十分なデータを受け取ったかどうかを判断する場所です。これが発生するまで、ネットワーク受信バッファにデータを残さないでください。ネットワーク受信バッファーの場合、循環バッファーを使用すると、バッファーを再利用するというアイデアに役立つと思います。うまくいけば、あなたはメッセージサイズのアイデアを持っています。これは、バッファのサイズを決定するのに役立ちます。循環バッファの読み取りポインタと書き込みポインタが出会ったときにアサート(または同様のもの)する場合は、バッファのサイズを増やします。バッファのサイズが十分に大きくなると、

于 2009-09-11T21:21:19.240 に答える