recv() komplett auslesen?
-
Hallo,
Ich habe eine Applikation, welche ein GET auf eine Homepage sendet, das zurückgesendete Ergebnis soll nun komplett ausgelesen werden, mein Problem ist:
char buffer [1000]; recv (socket, buffer, 1000, 0);
Das hier nur 1000 Zeichen eingelesen werden!
Wie schaffe ich es, dass das Programm einfach ohne "Limit" die Ausgabe vom Server via recv() einliest?Danke vielmals!
-
Wenn du mit nichtblockierenden Sockets arbeitest, dann einfach so lange lesen, bis recv -1 zurück gibt und errno EAGAIN anzeigt.
Oder besser: einfach so lange lesen, bis die Antwort zu Ende ist. HTTP gibt dir ja Informationen, wann die Antwort zu Ende ist bzw. wie lang die ist.
-
Und wenn ich mit blockierenden sockets arbeite?
kannst du mir einen link für nichtblockierende geben?
-
Ich hatte auch ein paar Problemchen beim Empfang auf nichtblockierenden Sockets, habe es aber so in den Griff bekommen :
#define READBUF 1024 //... char buffer[READBUF]; int iReadBytes = 0; string strIn; /*Ich hab hier statt einem weiteren (festen) char-array einen string benutzt, weil meine Funktion strings zurückgeben soll. Vor allem aber erweitern sich strings dynamisch !*/ do { iReadBytes = recv(iSocket,buffer,READBUF-1,MSG_NOSIGNAL); //Signals sind hier abeschaltet ! if (iReadBytes > 0) { for (int i=0;i<=iReadBytes;i++) { strIn += buffer[i-1]; } } }while (iReadBytes > 0); if (iReadBytes ==0) { //Fehlerbehandlung für Abbruch der Verbindung } if (iReadBytes < -1) { //Fehlerbehandlung für Socket-Fehler }
Es ist korrekt, wenn recv -1 zurückgibt, sobald keine Daten zum Lesen mehr vorhanden sind (EWOULDBLOCK oder EAGAIN), deswegen hab ich mir die Überprüfung auf weitere Fehlercodes bei -1 hier gespart.
Es findet sich im Netz oft die Methode, an die Stelle iReadBytes den Inhalt von buffer (ab der Stelle, wo das Array ungenutzt ist) zu terminieren, um sich die for-Schleife zu sparen und ein ordentlich terminiertes Array zu erhalten. Das dürfte bei blockierenden Sockets sogar gehen. In den Buffer selbst hineinzuschreiben (den recv schon zum Schreiben benutzt) ist allerdings etwas unsauber. In meinem Fall hat recv sogar immer mit 0 abgebrochen, wenn ich den buffer an einer Stelle vor oder gleich buffer[iReadBytes] beschreiben wollte - also besser Stück für Stück die bytes rüberkopieren, bevor buffer[] wiederverwendet wird.
Der string ist dabei dynamisch, ich kann also durch die Schleife den buffer-inhalt problemlos so oft in den string hineinstopfen bis dieser größer wird als der Buffer selbst.
Edit : Fehler korrigiert, hatte strlen(buffer) anstatt sizeof(buffer) im recv geschrieben. Muss heissen :
iReadBytes = recv(iSocket,buffer,sizeof(buffer),MSG_NOSIGNAL); //Signals sind hier abeschaltet !
Das kommt halt davon, wenn man auf dem einen Rechner das Forum, auf dem anderen den Code hat und zu faul ist eben rüberzuwechseln damit man copy&pasten kann...
-
HaRo: Das strlen() im recv() ergibt doch überhaupt keinen Sinn, strlen() ermittelt die Länge eines nullterminierten Strings, in deinem Buffer steht nur Murks drin. Du brauchst sizeof stattdessen!
Grundlagen
-
Danke, stimmt ! Da hab ich mich beim abtippen ins Forum voll versägt.
strlen würd wohl nen hübschen Speicherzugriffsfehler geben.
Einfacher zu begreifen ists eh mit ner Konstanten, habs oben korrigiert.
-
hi zusammen.
hab im moment das problem, dass mein socket nix empfangen will oO
hab mittlerweile auch methoden von anderen leuten zum empfangen benutzt (als letztes die oben gepostete).
aber es kommt bei mir einfach nichts an ?!
hier mal meine funktion:int ReceiveFromClient() { char buffer[BUFFSIZE]; string message = ""; int bytes; do { bytes = recv(sock, buffer, sizeof(buffer) - 1, 0); // Alles ok if (bytes > 0) { // Datenmüll löschen buffer[bytes] = '\0'; // Zum testen, ob bzw. wie oft er in diese Funktion reinkommt Log(buffer); for (int i = 0; i < sizeof(buffer) - 1; i++) message += buffer[i-1]; return 0; } } while (bytes > 0); // Fehler beim Empfangen if (bytes == -1) { //Log("Receiving failed"); return 1; } // Verbindung getrennt else if (bytes == 0) { Log("Connection closed"); return 2; } }
der aufruf sieht so aus:
do { usleep(5); ReceiveFromClient(); } while (true);
achja: ich programmiere unter linux.
-
k, habs gelöst -> falschen socket benuttz zum lesen