Binärdaten über Sockets empfangen?



  • int amount ) //warum denn int?

    Weil recv einen int liefert.

    char *tmp = new char[m_data_size+amount+1]; //aua

    Was ist hier denn schon wieder aua?

    if( !tmp ) //new gibt nicht 0 zurück

    Die Kritik daran hab ich erwartet und akzeptiere ich.

    Ansonsten schreibe ich seit über 20 Jahren Programme, die auch ohne exceptions fehlerfrei funktionieren.

    Problem war: ich musste in einem download beliebiger Größe nach mehreren Schlüsselwörtern suchen:
    - Download nach Schlüsselwort durchsuchen
    - wenn Schlüsselwort nicht gefunden, download - (Länge des längsten Schlüsselworts - 1) speichern und weiter

    Und wie würde ich einen vector<char> nach Schlüsselwörtern durchsuchen?



  • EOP schrieb:

    int amount ) //warum denn int?

    Weil recv einen int liefert.

    Was hat recv denn mit CCharBuffer zu tun? Genau, gar nichts!

    EOP schrieb:

    char *tmp = new char[m_data_size+amount+1]; //aua

    Was ist hier denn schon wieder aua?

    Dein Steinzeit-Compiler kennt anscheinend vector nicht oder du bist noch verkalkter als jener.

    EOP schrieb:

    if( !tmp ) //new gibt nicht 0 zurück

    Die Kritik daran hab ich erwartet und akzeptiere ich.

    .. wenn nackte Tatsachen nichts mehr ausrichten können.

    EOP schrieb:

    Ansonsten schreibe ich seit über 20 Jahren Programme, die auch ohne exceptions fehlerfrei funktionieren.

    Das ist jetzt nicht dein Ernst, oder?

    EOP schrieb:

    Und wie würde ich einen vector<char> nach Schlüsselwörtern durchsuchen?

    Das ist nicht mehr komisch, du kannst aufhören.



  • Was bist du denn für ein Depp? Nur Gemecker aber nix Konstruktives von dir. Absolut nix.

    Und wie würde ich einen vector<char> nach Schlüsselwörtern durchsuchen?

    Antworte bitte.



  • In C gibt es weder vector<char> noch new char[...]. Also wenn du Fragen zu vector<char> hast, dann stell sie bitte im C++-Forum. Die ganze Diskussion ist sicher wenig hilfreich für den Op.



  • rüdiger schrieb:

    In C gibt es weder vector<char> noch new char[...]. Also wenn du Fragen zu vector<char> hast, dann stell sie bitte im C++-Forum. Die ganze Diskussion ist sicher wenig hilfreich für den Op.

    Dann nimm eben malloc und free.



  • EOP schrieb:

    rüdiger schrieb:

    In C gibt es weder vector<char> noch new char[...]. Also wenn du Fragen zu vector<char> hast, dann stell sie bitte im C++-Forum. Die ganze Diskussion ist sicher wenig hilfreich für den Op.

    Dann nimm eben malloc und free.

    realloc. Aber selbst dann hat dein Code noch die angesprochenen Probleme und vorallem auch eine schlechte Allokierungsstrategie. Sobald du einmal die Kapazität erreicht hast, hast du dann ein realloc pro recv!



  • rüdiger schrieb:

    EOP schrieb:

    rüdiger schrieb:

    In C gibt es weder vector<char> noch new char[...]. Also wenn du Fragen zu vector<char> hast, dann stell sie bitte im C++-Forum. Die ganze Diskussion ist sicher wenig hilfreich für den Op.

    Dann nimm eben malloc und free.

    realloc. Aber selbst dann hat dein Code noch die angesprochenen Probleme und vorallem auch eine schlechte Allokierungsstrategie. Sobald du einmal die Kapazität erreicht hast, hast du dann ein realloc pro recv!

    Das war ja nur ein Teil einer Klasse um irgendeine binäre Geschichte zu lösen.

    Sobald keins der Schlüsselwörter gefunden wurde, wird der Puffer (minus Länge des längsten Schlüsselworts - 1) geschrieben, Rest an den Anfang verschoben und wiederverwendet.
    Nix mit ständigem realloc.

    Außerdem lese ich nie mehr als der Puffer groß ist. Da gibt's höchstens am Anfang mal ein "realloc".
    Würde ich den Puffer von Anfang an mit (Größe x + Länge des längsten Schlüsselworts) allozieren und nur immer Größe x lesen, gäb's eigentlich nie ein realloc.



  • EOP schrieb:

    Und wie würde ich einen vector<char> nach Schlüsselwörtern durchsuchen?

    Ist das deine Vorstellung von seit 20 Jahren programmieren? 😮
    Egal wie du vorher nach Schlüsselwörtern gesucht hast, mit dem vector wird es letztlich genau so funktionieren.

    @TE
    Eine einfache Möglichkeit ist, den empfangenen Puffer immer gleich in eine Datei zu schreiben. Dann musst du dich um das malloc/realloc Gefrickel nicht kümmern.



  • BlackCubeX schrieb:

    Hey,
    wie der Titel schon sagt arbeite ich an einem einfachen HTTP 1.0 Client, habe aber Probleme mit Binärdaten. Textdateien lassen sich einfach über

    do {
            count = recv( sock, buffer, sizeof(buffer), 0);
    		strcat(content, buffer);
        }
        while (count > 0);
    

    empfangen.
    Wenn ich aber nun z.B. ein PNG anfordere und in eine Datei schreibe, ist diese nicht lesbar.

    Wie du schon richtig erkannt hast, kann das für Binärdateien nicht funktionieren, da strcat verwendet wird, was nur Strings richtig verarbeitet.

    unsigned char buffer[1024],*b=0;
    size_t p=0;
    while( (count = recv( sock, buffer, 1024, 0))>0 )
    {
      b=realloc(b,p+count);
      memcpy(b+p,buffer,count);
      p+=count;
    }
    


  • cooky451 schrieb:

    EOP schrieb:

    Und wie würde ich einen vector<char> nach Schlüsselwörtern durchsuchen?

    Ist das deine Vorstellung von seit 20 Jahren programmieren? 😮

    Das ist nicht meine Vorstellung sondern die Realität.

    Außerdem liebe ich memcpy, memmove, etc. 😋



  • Danke für eure ganzen Antworten, ich finds lustig, wie hier auf die kleinste Frage immer gleich eine riesen Diskussion ausbricht ^^
    Sowas wie von Wutz hätte ich eigentlich erwartet, aber das von E0P sirht auch interressant aus und wird bestimmt noc Verwendung finden 🙂
    Ich hab die Sache inzwischen übrigens einfach mit

    outfile.write(buffer, count);
    

    gelöst 😃

    LG
    BCX



  • BlackCubeX schrieb:

    Danke für eure ganzen Antworten, ich finds lustig, wie hier auf die kleinste Frage immer gleich eine riesen Diskussion ausbricht ^^

    Das ist der Sinn eines Forums. 😉

    BlackCubeX schrieb:

    aber das von E0P sirht auch interressant aus und wird bestimmt noc Verwendung finden 🙂

    Lieber nicht.

    BlackCubeX schrieb:

    Ich hab die Sache inzwischen übrigens einfach mit

    outfile.write(buffer, count);
    

    gelöst 😃

    Also meine Variante. 🕶



  • Wutz schrieb:

    unsigned char buffer[1024],*b=0;
    size_t p=0;
    while( (count = recv( sock, buffer, 1024, 0))>0 )
    {
      b=realloc(b,p+count);
      memcpy(b+p,buffer,count);
      p+=count;
    }
    

    Du verwendest realloc falsch http://www.c-plusplus.net/forum/206606
    Außerdem ist ein realloc pro recv keine gute Allokierungsstrategie.



  • Ich verwende realloc richtig.
    Und deine "Strategie" der Vermeidung von vielen realloc ist subjektiv, scheitert ein realloc mit diesen minimalen Raten irgendwann mal, hast du mit deinem Programm eh ganz andere Probleme.
    Deswegen kann man auch statt *b=0 *b=malloc(100000000) verwenden, was aber mit der Frage nichts zu tun hat.



  • Wutz schrieb:

    Ich verwende realloc richtig.

    Nein, siehe Link (3.2). realloc kann NULL zurück liefern und das ist nicht mal so unwahrscheinlich, wenn man größere Daten über http laden will. Dann hast du n Speicherlack, versuchst auf NULL zu kopieren, etc.



  • Kannst du lesen? Nein kannst du nicht, zumindest nicht bis zum Ende meines Beitrages.



  • cooky451 schrieb:

    BlackCubeX schrieb:

    aber das von E0P sirht auch interressant aus und wird bestimmt noc Verwendung finden 🙂

    Lieber nicht.

    Na was denn? Das ist ordentlich programmiert bis auf den Test, ob tmp NULL ist.



  • EOP schrieb:

    Na was denn? Das ist ordentlich programmiert bis auf den Test, ob tmp NULL ist.

    Ja.. bis auf:

    - Es ist C++ und kein C, und wenn man C++ hat sollte man lieber gleich std::vector<char> nutzen.

    Aber nehmen wir mal an es wäre C und du hättest malloc/free statt new/delete genutzt:

    - Alles was du empfängst muss mit so einem Puffer sinnloserweise ein Mal mehr kopiert werden.
    - p sollte const char* sein. (Oder gleich const void*)
    - amount sollte gleich size_t sein.
    - Du machst sinnloserweise eine Nullterminierung im Puffer selbst.
    - Du könntest gleich auf m_data_size+amount >(=) m_buf_size testen, entsprechend Speicher reservieren und den alten Kram kopieren, dann würdest du einiges an Coderedundanz sparen und das Ganze wäre viel übersichtlicher.
    - Du solltest realloc nutzen. ( 🤡 )



  • Das mit const ist ok.

    Der Hintergrund wieso ich die ganze Klasse überhaupt geschrieben hatte ist der, daß ich auch "transfer-encoding: chunked" mit binären Daten runterladen und nach Schlüsselworten durchsuchen musste.

    Und welchen Vorteil hätte ich wenn ich malloc statt new benutzen würde? Erschließt sich mir nicht so ohne weiteres.

    Nullterminierung ist deshalb weil ich je nach übertragenem mime-Typ dann mit strstr suche. (Jetzt nicht auch noch an strstr rummeckern!)



  • Wutz schrieb:

    Kannst du lesen? Nein kannst du nicht, zumindest nicht bis zum Ende meines Beitrages.

    Wer muss denn gleich persönlich werden. Es ist eben nicht unrealistisch das realloc fehlschlägt. Es geht um eine HTTP-Implementierung und da ziehen Leute gerne mal ein DVD-Image oder andere große Dateien die möglicherweise nicht in den Speicher passen. Wenn du gerne Code schreibst, der dir in Fehlersituationen um die Ohren fliegt, dann bitte tu das. Aber das solltest du nicht anderen Leuten empfehlen.


Anmelden zum Antworten