Socket: Puffer füllen



  • Hallo,

    ich muss in einem Programm 100kB von einem Socket in einen Puffer übertragen. Da der Server aber grundsätzlich kleinere Blöcke sendet (~1,5kB), halte ich es für die beste Lösung einen zweiten, kleineren Puffer zu deklarieren, dessen Inhalt dann an den des ersten angehängt wird. Da es sich bei den Daten um Binärdaten (kein Text!) handelt, kann ich als Puffer keinen std::string verwenden. Hier mal ein kurzer Beispielcode

    void *in; // Hauptpuffer
    void *buf;
    unsigned empf // Anzahl der bereits empfangen Bytes
    unsigned aktuell; //Anzahl der diesmal empfangen Bytes
    do {
        aktuell = recv (socket, buf, 100000, 0);
        empf += aktuell;
        memcpy (in, buf, aktuell); // Liefert leider einen SegmentationFault
    } while (empf < 100000);
    

    Kann mir jemand hier weiterhelfen? Wie kann man die Daten an den großen Puffer anhängen?
    Die Daten müssen letztendlich als unsigned char* zur Verfügung gestellt werden. Sollte ich hierfür besser static_cast oder reinterpret_cast verwenden?

    Danke



  • Du stellst weder für in noch für buf Speicher bereit, so kann das also nicht funktionieren.
    So würde es gehen:

    unsigned char in[100000]; // Hauptpuffer
    unsigned char buf[10000];
    unsigned empf=0; // Anzahl der bereits empfangen Bytes
    int aktuell; //Anzahl der diesmal empfangen Bytes
    do
    {
        aktuell = recv (socket, buf, 10000, 0);
        if (aktuell==SOCKET_ERROR)throw eine_exception_oder_aehnliches();    
        memcpy (in + empf, buf, aktuell);
        empf += aktuell;
    }
    while (empf < 100000);
    

    Das Herumkopieren würde so aber reichlich wenig Sinn machen.
    Also doch lieber so:

    unsigned char in[100000]; // Hauptpuffer
    unsigned empf=0; // Anzahl der bereits empfangen Bytes
    int aktuell; //Anzahl der diesmal empfangen Bytes
    do
    {
        aktuell = recv (socket, in+empf, 100000-empf, 0);
        if (aktuell==SOCKET_ERROR)throw eine_exception_oder_aehnliches();    
        if (aktuell==0)throw auch_eine_exception_oder_aehnliches();    
        empf += aktuell;
    }
    while (empf < 100000);
    


  • @basti33:
    Die 2. Variante die Nanyuki dir gezeigt hat ist auch das "wie man es üblicherweise macht". Nur zur Info.
    Oft macht es auch Sinn genau dieses Codestück in eine eigene Funktion zu packen der man dann die Länge der zu empfangenden Daten übergibt, also das was hier jetzt mit 100000 "hardcoded" ist.



  • Wenn recv SOCKET_ERROR zurückgibt, würde ich den WSA-Last-Error noch auf WSAEWOULDBLOCK testen, was dann kein Fehler ist, sind dann nur grad keine Daten im Empfangspuffer vorhanden (also dann einfach den "memcpy" und "+=" Teil überspringen).


Anmelden zum Antworten