Mit Sockets größere Dateien downloaden
-
dgrat_ schrieb:
klingt relativ einfach und elegant
Ganz so einfach wie es sich anhört ist es nicht.
Angenommen du benutzt die einfache Variante, nämlich HTTP/1.0:
Um das Header-Ende zu finden musst du die empfangenen Daten solange an einen Puffer anhängen bis du "\r\n\r\n" gefunden hast (Ich habe schon header gehabt bei denen allein das Cookie über 2000 Bytes lang war).
Wenn es auch mit Binärdaten funktionieren soll, musst du memmove/memcpy/strstr benutzen. Dann musst du den Puffer u.U. auch dynamisch vergrößern und umkopieren.
Ab dem Moment wo du das Header-Ende gefunden hast kannst du munter drauflosspeichern - vorausgesetzt du hast ein 200 OK bekommen.
Edit:
Um effektiv zu suchen merkst du dir die Position im Puffer bis zu der du "\r\n\r\n" nicht gefunden hast, ziehst 3 Bytes ab und suchst nächstes Mal ab der Position.
-
EOP schrieb:
Dann musst du den Puffer u.U. auch dynamisch vergrößern und umkopieren.
Wenn einen die Daten im Endeffekt eh nicht interessieren, kann man auch einfach immer neu empfangen. Wenn man dann noch 100%tige Sicherheit haben will, muss man halt drauf achten, dass am Ende des Puffers kein "\r\n" (oder sowas) steht, aber das ist schon sehr unwahrscheinlich
-
cooky451 schrieb:
EOP schrieb:
Dann musst du den Puffer u.U. auch dynamisch vergrößern und umkopieren.
Wenn einen die Daten im Endeffekt eh nicht interessieren, kann man auch einfach immer neu empfangen. Wenn man dann noch 100%tige Sicherheit haben will, muss man halt drauf achten, dass am Ende des Puffers kein "\r\n" (oder sowas) steht, aber das ist schon sehr unwahrscheinlich
Ein minimales Interesse an den Header-Daten muss man schon haben: angenommen du bekommst kein 200 OK.
Oder dein Puffer ist kleiner als die Header-Größe. Was dann?
Edit:
Unwahrscheinlich heisst nicht unmöglich. Ein vernünftiges Programm fängt alle möglichen Fehler ab. Auch ohne 1000 try-catch-Blöcke.
-
[quote="EOP"]
cooky451 schrieb:
Ein minimales Interesse an den Header-Daten muss man schon haben: angenommen du bekommst kein 200 OK.
Oder dein Puffer ist kleiner als die Header-Größe. Was dann?
Nehmen wir doch einfach mal eine kleine Puffergröße von 256.
1. Solange empfangen bis "200 OK" geparst wurde. (Da dürfte einmal reichen :D)
2. Solange immer wieder neu empfangen bis "\r\n\r\n" gefunden wurde.fertig
Ich verstehe das große Problem nicht, da brauchste keine dynamische Speicherverwaltung.
-
[quote="cooky451"]
EOP schrieb:
cooky451 schrieb:
Ein minimales Interesse an den Header-Daten muss man schon haben: angenommen du bekommst kein 200 OK.
Oder dein Puffer ist kleiner als die Header-Größe. Was dann?
Nehmen wir doch einfach mal eine kleine Puffergröße von 256.
1. Solange empfangen bis "200 OK" geparst wurde. (Da dürfte einmal reichen :D)
2. Solange immer wieder neu empfangen bis "\r\n\r\n" gefunden wurde.fertig
Ich verstehe das große Problem nicht, da brauchste keine dynamische Speicherverwaltung.Mein Header ist 257, 258 oder 259 Bytes lang - wo findest du dann das Ende? Nie.
-
EOP schrieb:
Mein Header ist 257, 258 oder 259 Bytes lang - wo findest du dann das Ende? Nie.
Hä? Kennste Schleifen?^^
Vielleicht das Ganze mal in Pseudocode verdeutlichen:int rval = 0; char buf[0x100] = {0}; while (!FoundEnd(buf)) rval = recv(sock, buf, sizeof(buf) - 1, 0), buf[rval] = '\0';
Edit:
Denke ich habe dich falsch verstanden. FoundEnd() merkt sich natürlich wenn die letzten Zeichen '\r' || '\n' sind. Ist ja nicht das Problem
-
cooky451 schrieb:
EOP schrieb:
Mein Header ist 257, 258 oder 259 Bytes lang - wo findest du dann das Ende? Nie.
Hä? Kennste Schleifen?^^
Hä, kannste denken?
253 Bytes + "\r\n\r"
254 Bytes + "\r\n"
255 Bytes + "\r"Was hilft dir da deine Schleife?
-
Siehe edit
-
Auch Pseudocode:
if last == "\r\n\r\n" else if last == "\r\n\r" && first == "\n" else if last == "\r\n" && first == "\r\n" else if last == "\r" && first == "\n\r\n" else ...
Wo hast du denn gelernt so effektiv zu programmieren?
Oder noch eine Stufe besser:
if last == "\r\n\r\n" else if last == "\r\n\r" && first == "\n" else if last == "\r\n\r" && first != "\n" else if last == "\r\n" && first == "\r\n" else if last == "\r\n" && first != "\r\n" else if last == "\r" && first == "\n\r\n" else if last == "\r" && first != "\n\r\n" else ...
-
Ich dachte da mehr an sowas:
(Ungetestet, sollte aber funktionieren)const char* FindEnd(const char *buf) { static int last = 0; if (last) { while ((*buf == '\r' || *buf == '\n') && *buf) if (*buf++ == '\n') return buf; if (!*buf) return 0; } if (strstr(buf, "\n\r\n")) return strstr(buf, "\n\r\n") + 3; if (buf[strlen(buf) - 1] == '\n' || (buf[strlen(buf) - 1] == '\r' && buf[strlen(buf) - 2] == '\n')) last = 1; else last = 0; return 0; }
Wo hast du denn gelernt so effektiv zu programmieren?
In der Compilerschule
(Edit: Oups, eine kleine Änderung :D)