Malloc dynamisch mit recv



  • Gibt es eine möglichkeit malloc dynamisch auf die passende größe zu bringen, sizeof() geht nicht, dar ich die länge vor dem recv noch nicht weißt, hat jemand für so etwas einen Lösungsansatz.

    #define BUF 4096
    
    string netserver::getdata()
    {
    string data;
    char *temp=(char*)malloc(BUF);
    recv(serversocket,temp, sizeof(temp),0 );
    data = temp;
    return data;
    }
    


  • Blockweise empfangen, danach zusammensetzen und free nicht vergessen.

    Edit: Oder in Protokoll einbauen, z.B. ersten 4 Bytes sind immer die Grösse, danach empfangen bis alle Daten da sind, danach wieder die Grösse empfangen.


  • Administrator

    Zuerst, wenn du es mir erlaubst, ein paar Anmerkungen zu deinem Code:

    // #define BUF 4096
    // Unter C hat man define für Konstanten verwendet, unter C++ hat man das Schlüsselwort const.
    const int BUF = 4096;
    
    // Ich würde allerdings dazu raten, sowas nicht als globale Variable zu definieren.
    
    string netserver::getdata()
    {
      string data;
      // char *temp=(char*)malloc(BUF);
      // Wieso malloc? Nimm new, wir sind in C++
      // char* temp = new char[BUF];
      // Ich würde aber den Stack empfehlen, bei so geringer Speichermenge:
      char temp[BUF] = { 0 };
    
      // Ansonsten std::vector, da so der Speicher sicher verwaltet ist.
      // Stichwort RAII
    
      // recv(serversocket, temp, BUF, 0);
      // sizeof(temp) mit deinem vorherigen vorgehen, hätte wohl 4 zurückgeliefert
      // und nicht die Arraygrösse. Wieso nicht gleich BUF verwenden?
    
      // Bist du sicher, dass der C String nullterminiert sein wird?
      // Sonst gibt das undefiniertes Verhalten.
      data = temp;
    
      return data;
    }
    

    Zu deinem Problem, da gibt es eigentlich 3 Möglichkeiten:
    1. Du liest immer Chunks aus, bis du festgestellt hast, dass das Ende einer Datenmenge erreicht hast. Das Protokoll muss also einen Delimiter definieren.
    2. Das Protokoll legt feste Grössen fest.
    3. Das Protokoll übermittel in einer festen Grösse zuerst die Grösser der Daten, welche reinkommen.

    Also grundsätzlich sind alle Lösungen darauf ausgelegt, dass das Protokoll, mit welchem kommuniziert wird, sinnvoll aufgebaut ist. Sonst gibt es da keine Möglichkeit, ausser dein Programm kann hellsehen.

    Grüssli

    PS: Sowas gehört wohl nicht wirklich ins C++ Forum.



  • Nur das mit der if anweisung haut leider noch nicht hin. Sobald der Client die Daten übermittel übersendet er doch null oder ?

    bool netserver::getdata(Data data)
    {
    const int BUF = 4096; 
    char temp[BUF] = { 0 }; 
    recv(serversocket,temp, BUF,0 );
    if(temp == 0) {return 1;}
    else
    data.push_back(temp);
    cout << "getdata: " << temp <<endl;
    return 0;
    }
    


  • unbedingt den return wert von recv(..) prüfen.
    Simon



  • habe es:
    bool netserver::getdata(Data data)
    {
    const int BUF = 4096;
    char temp[BUF] = { 0 };
    if(recv(serversocket,temp, BUF,0 ) ==0) {return 1;}
    else
    data.push_back(temp);
    cout << "getdata: " << temp <<endl;
    return 0;
    }



  • Und die anzahl gelesener bytes.
    Benutzt Du eigentlich UDP oder TCP?
    Simon



  • tcp



  • int ret = recv(blah);
    if( ret > 0 )
    	continue;
    else if( ret == 0 )
    	finished();
    else if( ret < 0 )
    	error();
    


  • else if( ret < 0 )
    	error();
    

    Ein else würde hier reichen. 😉



  • Nexus schrieb:

    else if( ret < 0 )
    	error();
    

    Ein else würde hier reichen. 😉

    wird der compiler auch merken 😛



  • unskilled schrieb:

    wird der compiler auch merken 😛

    Jaja, sich immer auf Optimierungen verlassen und nicht mehr selber denken. Schade nur, wenn dann eine erwartete Optimierung nicht eintritt. 😉



  • Nexus schrieb:

    unskilled schrieb:

    wird der compiler auch merken 😛

    Jaja, sich immer auf Optimierungen verlassen und nicht mehr selber denken. Schade nur, wenn dann eine erwartete Optimierung nicht eintritt. 😉

    if( ret > 0 )
        continue;
    else if( ret == 0 )
        finished();
    else if( ret < 0 )
        error();
    

    sollte doch eh nur ein vergleich zwischen ret und 0 sein und dann jmp_bigger, jmp_equal bzw. jmp_lower?!
    bin jz nur zu faul, das auszuprobieren ^^

    bb



  • Nexus schrieb:

    else if( ret < 0 )
    	error();
    

    Ein else würde hier reichen. 😉

    Schon klar - war ja auch nur "copy + pasted" 😉



  • unskilled schrieb:

    Nexus schrieb:

    unskilled schrieb:

    wird der compiler auch merken 😛

    Jaja, sich immer auf Optimierungen verlassen und nicht mehr selber denken. Schade nur, wenn dann eine erwartete Optimierung nicht eintritt. 😉

    if( ret > 0 )
        continue;
    else if( ret == 0 )
        finished();
    else if( ret < 0 )
        error();
    

    sollte doch eh nur ein vergleich zwischen ret und 0 sein und dann jmp_bigger, jmp_equal bzw. jmp_lower?!
    bin jz nur zu faul, das auszuprobieren ^^

    bb

    Wahrscheinlich:
    ja
    je
    und ...


Log in to reply