Pregunta

Al leer datos a través de la red, especifica un búfer para recibir los datos en:

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

Ahora, mi primer pensamiento es, por supuesto, reutilizar el búfer de recepción declarándolo como una variable miembro de la clase. Mi siguiente problema es que no he recibido todos los datos que esperaba, por lo que necesito almacenarlos en un búfer. Esto es fácil de lograr mediante el seguimiento del recuento de bytes recibidos y la especificación del desplazamiento:

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

Ahora, el problema aquí es que si aún no es suficiente, supongo que necesito aumentar el búfer, lo que significa copiar la memoria y continuar recibiendo en este búfer. Suponiendo que algo saliera mal, este búfer continuaría creciendo y, si se recibían mensajes lo suficientemente grandes, el sistema se quedaría sin memoria.

¿Alguna idea de cómo manejar esto correctamente? ¿Hay una mejor manera de recibir los datos que simplemente llenar, copiar, crecer, llenar, copiar, crecer de lo que estoy hablando?

¿Fue útil?

Solución

leer en trozos:

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
}

Otros consejos

Antes de comenzar con SYstem.Net.Sockets.Socket, ¿está seguro de que no puede usar System.Net.Sockets.TcpClient (o UdpClient) que hace todo el trabajo desordenado del búfer por usted y lo transforma en un sistema de fácil manejo? streaming?

Si no, recuerde que la cantidad de datos que recibe no tiene que ser igual a lo que solicita, por lo que siempre debe mirar el valor de retorno de la función de recepción. Y, la única forma de no quedarse sin memoria es mediante el procesamiento de lo que recibe.

Primero, separe el código para recibir los datos y procesarlos. El búfer de recepción solo debe contener los datos hasta que el código tenga la oportunidad de copiarlos en el área de procesamiento. El área de procesamiento es donde determinará si ha recibido suficientes datos para hacer algo útil. No deje los datos en el búfer de recepción de red hasta que esto suceda. Para el búfer de recepción de red, creo que usar un búfer circular lo ayudará con su idea de reutilizar un búfer. Con suerte, tienes una idea de los tamaños de los mensajes. Eso ayudará a determinar el tamaño del búfer. Si afirma (o algo similar) cuando se encuentran los punteros de lectura y escritura del búfer circular, aumente el tamaño del búfer. Una vez que el tamaño del búfer es lo suficientemente grande, debería poder leer suficientes datos del búfer en el código de procesamiento a una velocidad lo suficientemente rápida como para que el búfer circular no se desborde.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top