2012-08-24 11 views
6

En C Tenía código de trabajo, pero no tenía idea de por qué funcionaba, así que comencé a reescribirlo para poder entender lo que estaba pasando.Cómo almacenar la salida de recv()?

Hasta ahora todo bien! Reescribí y estoy 90% seguro de entender todo lo que está sucediendo ahora; Sin embargo, el problema es que no tengo idea de cómo almacenar el fragmento de datos recibido por recv (databff) en mi memoria intermedia previamente asignada (htmlbff).

considere el siguiente código (nótese que me desnudé esto abajo un poco, por lo que sólo incluye los conceptos básicos, por ejemplo, sin reasignación de memoria o escape, protección, etc ...):

#define BUFFERSIZE 4096 
#define MAXDATASIZE 256 

char *htmlbff, databff[MAXDATASIZE]; 
int c, i = BUFFERSIZE, q = 0;   
if(!(htmlbff = malloc(i))) 
{ 
    printf("\nError! Memory allocation failed!"); 
    return 0x00; 
} 
while((c = recv(sock, databff, MAXDATASIZE, 0)) > 0) 
{ 
    /*memory checks stripped out since they are irrelevent for this post*/ 
    /*store data to the appropriate area in htmlbff*/ 
    q += c;   
} 

Así que (si Estoy haciendo esto bien, y las cosas van como creo) c es el tamaño del fragmento de datos actual, y q es la cantidad total de datos recibidos hasta ahora (q se incrementa en c cada vez que se repite el ciclo). Por el momento estoy usando q para el manejo de la memoria (en caso de que alguien se esté preguntando) pero creo que también tendrá un propósito en la solución a este problema.

En cualquier caso, la pregunta que hago es en relación con el segundo comentario. ¿Cómo guardo los datos de recv en htmlbff correctamente?

Respuesta

2

Uso memcpy, y compensar htmlbff por q:

memcpy(htmlbff + q, databff, c); 

Puede similarmente recv directamente en htmlbff:

c = recv(sock, htmlbff + q, MAXDATASIZE, 0)); 

Pero está bien para mantener una memoria intermedia separada, y dependiendo de su código completo , puede aclarar las cosas.

Asegúrese de agregar cheques contra BUFFERSIZE para no copiar más allá de los límites de htmlbff. Mencionó que ha eliminado el manejo de realloc, por lo que quizás ya esté manejando esto.

Sus nombres constantes son un poco confusas, cuando almacenamiento temporal de datos que usaría BUFFERSIZE para indicar el tamaño de cada trozo , es decir, el tamaño de databff.

+0

Me gusta mucho esta respuesta, gracias. Encontré este más útil porque ahora puedo omitir el uso del búfer y escribir directamente en htmlbff. –

5

Utilice memcpy() para copiar (agregar) datos al htmlbff pero también debe asegurarse de no exceder el tamaño de htmlbff. Deje de recibir datos cuando se ha recibido BUFFERSIZE bytes o use realloc() para ampliar htmlbff para que contengan más datos.

Por ejemplo:

char* htmlbff; 
size_t htmlbff_size = BUFFERSIZE; 
htmlbff = malloc(htmlbff_size); 

if (htmlbff) 
{ 
    while((c = recv(sock, databff, MAXDATASIZE, 0)) > 0) 
    { 
     if (c + q > htmlbff_size) 
     { 
      htmlbff_size *= 2; /* Arbitrary doubling of size. */ 
      char* tmp = realloc(htmlbff, htmlbff_size); 
      if (tmp) 
      { 
       htmlbff = tmp; 
      } 
      else 
      { 
       /* memory allocation failure. */ 
       free(htmlbff); 
       htmlbff = 0; 
       break; 
      } 
     } 
     memcpy(htmlbff + q, databff, c); 
     q += c; 
    } 
} 
+0

Muy bien, gracias, y así es como estoy administrando mi memoria, excepto que he agregado otro paso para reajustar el tamaño del búfer a exactamente cuántos bytes necesito cuando termine de buclear. Nuevamente gracias por tu respuesta. –

1

que necesita para mantener la reasignación/ampliación de la memoria intermedia para adaptarse a todos los datos (si los datos leídos de la toma excede MAXDATASIZE) = De esa manera como recv lee los datos en el databff, su htmlbff puede crecer en la memoria y luego la nueva lectura se puede agregar a su htmlbff general.

q y c son como cursores para realizar un seguimiento de dónde se encuentra y qué tan lejos tiene que ir.

memcpy(htmlbff+q, databff, c); //Do this in your whle loop to append the data 
2

Lo que yo haría es recv() datos directamente en htmlbff, a menos que necesite hacer más procesamiento en él.

Asegúrese de que realloc()htmlbff cuando i - q es menos de MAXDATASIZE de manera que siempre hay espacio para otro recv().

Entonces llamarías a recv(sock, htmlbff + q, MAXDATASIZE, 0)

Cuestiones relacionadas