2012-08-24 10 views
6

In C hatte ich Arbeitscode, aber ich habe keine Ahnung, warum es funktionierte, also fing ich an, es neu zu schreiben, damit ich wirklich verstehen konnte, was vor sich ging.Wie speichert man die Ausgabe von recv()?

So weit so gut! Ich schrieb um und bin zu 90% sicher, dass ich alles verstehe, was gerade passiert; Das Problem ist jedoch, dass ich keine Ahnung habe, wie ich den Datenblock, der von recv (databff) empfangen wurde, in meinen vorbelegten Puffer (htmlbff) speichern kann.

Betrachten Sie den folgenden Code (beachten Sie, dass ich das ziemlich viel abgespeckte, so dass er nur die Grundlagen enthält, zB kein Gedächtnis Neuzuteilung oder Schutz auslaufen, 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;   
} 

So (wenn Ich mache das richtig, und die Dinge gehen so, wie ich denke, dass sie sind) c ist die Größe des aktuellen Datenblocks, und q ist die Gesamtmenge der bisher empfangenen Daten (q wird um c jedes Mal inkrementiert die Schleife wiederholt). Im Moment verwende ich q für die Speicherbehandlung (falls jemand sich wundern würde), aber ich glaube, dass es auch einen Sinn in der Lösung dieses Problems haben wird.

Auf jeden Fall ist die Frage, die ich stelle, in Bezug auf den zweiten Kommentar. Wie speichere ich die Daten von recv in htmlbff korrekt?

Antwort

2

Verwendung memcpy und Offset htmlbff von q:

memcpy(htmlbff + q, databff, c); 

Sie können in ähnlicher Weise recv direkt in htmlbff:

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

Aber es ist in Ordnung, einen separaten Puffer zu halten, und in Abhängigkeit von Ihrem vollständigen Code es kann die Dinge klarer machen.

Stellen Sie sicher, dass Sie Prüfungen gegen BUFFERSIZE hinzufügen, so dass Sie nicht über die Grenzen von htmlbff kopieren. Sie haben erwähnt, dass Sie realloc Handhabung entfernt haben, also behandeln Sie vielleicht bereits dies.

Ihre konstanten Namen sind ein wenig verwirrend, wenn Daten Pufferung würde ich BUFFERSIZE verwenden, um die Größe jeden chunk, das heißt, die Größe von databff anzuzeigen.

+0

Ich mag diese Antwort wirklich danke. Ich fand das am nützlichsten, da ich jetzt einfach den Puffer überspringen und direkt in htmlbff schreiben kann. –

5

Verwenden Sie memcpy() zum Kopieren (Anhängen) von Daten an die htmlbff, aber Sie müssen auch sicherstellen, dass Sie nicht die Größe von htmlbff überschreiten. Beenden Sie das Empfangen von Daten, wenn BUFFERSIZE Bytes empfangen worden sind, oder verwenden Sie realloc(), um htmlbff zu erweitern, um mehr Daten zu enthalten.

Zum Beispiel:

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

Sehr schön, danke, und das ist genau, wie ich meinen Speicher bereits verwalte, außer dass ich einen weiteren Schritt hinzugefügt habe, um die Größe des Puffers genau so neu zu verteilen, wie viele Bytes ich brauche, wenn ich fertig bin. Nochmals vielen Dank für Ihre Antwort. –

1

Sie benötigen eine Umschichtung zu halten/Erweiterung des Puffer alle Daten passen = auf diese Weise als recv liest Daten in das databff (wenn die Daten, die die Steckdose überschreitet MAXDATASIZE abgelesen), Ihr htmlbff kann im Speicher wachsen und dann kann der neue Lesevorgang an Ihren gesamten htmlbff angehängt werden.

q und c sind wie Cursor, um zu verfolgen, wo Sie gerade sind und wie weit Sie gehen müssen.

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

Was ich tun würde, ist recv() Daten direkt in htmlbff, es sei denn, Sie es Verarbeitung müssen tun.

Stellen Sie sicher, dass Sie realloc()htmlbff wenn i - q weniger als MAXDATASIZE ist so, dass es für eine andere recv() immer Raum.

Dann würden Sie anrufen recv(sock, htmlbff + q, MAXDATASIZE, 0)

Verwandte Themen