TCP-Verbindung aufbauen und Daten herunterladen
-
Hallo,
ich möcht zu einem Internetserver eine TCP Verbindung herstellen. Wenn die Verbindung steht, schicke ich einen String und erhalte als Antwort Daten. Wie man jetzt eine Internetdatei über http, also Port 80, in einen Buffer läd, weiss ich soweit und das klappt auch. Zuerst mache ich eine Anfrage wie groß die Datei ist, dannach erstelle ich einen Buffer mit der entsprechenden Größe und lade die Datei hinein.
Wie ist das aber, wenn man die Größe der empfangenen Daten im voraus nicht kennt. Wie geht man da vor? Ich weiss zwar, daß ein Buffer von vieleicht 20k ausreichen würde/könnte, aber ich würde da schon eine elegantere Methode vorziehen. Wer kann helfen?Danke schon mal,
Helmut
-
Man benutzt mindestens WinInet, außer man ist Masochist.
-
Hallo,
ich bin Masochist.
Helmut
-
ein teil runterladen, in ne datei speichern, weiterladen, schreiben, laden, schreiben,.... ,laden, schreiben - bis nixmehr da is^^
-
Sowas ähnliches findest Du hier:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-257326.html
-
@Helmut_:
Wie du es machen kannst, wenn du die Datei auf die Platte schreiben willst, hat MoepMoep ja schon beschrieben.Wenn du die Datei nur ins RAM laden willst, ohne sie auf die Platte zu schreiben, kannst du es ähnlich machen: du verwendest erstmal einen kleinen Puffer. Wenn der "voll" ist, forderst du einen grösseren Puffer an. Dann kopierst du die Daten aus dem kleineren Puffer an den Anfang des grösseren Puffers, und gibst den kleineren Puffer frei. Danach füllst den grösseren Puffer weiter mit empfangenen Daten auf. So lange, bis das File vollständig empfangen ist, oder auch der grössere Puffer wieder voll ist. Wenn auch der grössere Puffer voll ist, machst du einfach dasselbe nochmal: noch grösseren Puffer anfordern, Daten kopieren, alten Puffer freigeben, weitermachen.
Dass die Datei zuende ist, signalisiert der Server bei HTTP dadurch, dass er die Verbindung zu macht. Auf der Empfängerseite bekommst du das dadurch mit, dass recv() dir Null zurückliefert. Dann weisst du, dass du das File vollständig empfangen hast.
-
Hast du ihm std::vector verschwiegen weil er Masochist ist?

-
Helmut_ schrieb:
Hallo,
ich bin Masochist.
Helmut
Das war nicht mein Beitrag, sondern irgendein Faker.
Aber es stimmt schon ich benutze connect, send, recv und das klappt nun auch erfolgreich. Die Daten werden in einem mit malloc erzeugten Buffer geladen, und wenn eine bestimmte Grenze erreicht ist, dann wird der einfach mir realloc vergrössert.
Jetzt hab ich noch ein Problem, wie kann ich auf einen Timeout des Servers reagieren. Hier mal ein Teil meines Codes (die Sachen mit socket, connect und send hab ich mal weggelassen):ok = FALSE; gesamt_recieved = 0; position = big_buffer; do{ /* realloc Stuff here */ : : bytes_recieved = recv(sock, small_buffer, sizeof(small_buffer), 0); if(bytes_recieved == SOCKET_ERROR){ break; }else if(bytes_recieved == 0){ ok = TRUE; } memcpy(position, small_buffer, bytes_recieved); gesamt_recieved += bytes_recieved; position += bytes_recieved; : : : }while(ok == FALSE);Ich möchte gerne irgendwo den Fall abfangen, dass der Server schon Daten gesendet hat, jedoch irgendwann mittendrin aufgehört hat. Wie mache ich das und an welcher Stelle im Code?
-
was verstehst du bitte unter "timeout des servers"?
-
oO schrieb:
Hast du ihm std::vector verschwiegen weil er Masochist ist?

Nein, sondern weil ich mir ziemlich sicher war, dass er std::vector nicht kennt, und nichts damit anfangen kann.
-
hustbaer schrieb:
was verstehst du bitte unter "timeout des servers"?
Naja während der Übertragen bricht der Server aus irgendeinem Grund ab Daten zu senden. Ok ich kenn das mit dem Timeout jetzt nur von UDP, ich dachte bei TCP wird das auch benötigt. Ich frag halt mal blöd weil ich mich nicht auskenne.
hustbaer schrieb:
oO schrieb:
Hast du ihm std::vector verschwiegen weil er Masochist ist?

Nein, sondern weil ich mir ziemlich sicher war, dass er std::vector nicht kennt, und nichts damit anfangen kann.
Da hast du vollkommen Recht, damit kann ich nichts anfangen.
-
Naja während der Übertragen bricht der Server aus irgendeinem Grund ab Daten zu senden
hä?
bricht ab zu senden? das ist kein deutsch.
aber auch bei "hört auf zu senden" wüsste ich nicht was du meinst. schliesst er die verbindung? oder kommen einfach keine daten mehr, die verbindung bleibt aber bestehen?geh mal etwas grundlagen lernen (TCP, sockets, HTTP). es ist immer sehr mühsam wenn jemand kommt und was fragt, dem noch einiges an grundlagen fehlt.
-
Helmut_ schrieb:
Naja während der Übertragen bricht der Server aus irgendeinem Grund ab Daten zu senden.
normalerweise macht er das nicht. wenn der server die verbindung killt oder beendet, kommt recv mit 0 oder SOCKET_ERROR zurück. falls einer beim server einfach den stecker zieht, haste aber pech gehabt. du könntest mit setsockopt() und SO_KEEPALIVE das senden sogenannter 'keep-alive pakete' aktivieren, die der server beantworten muss. ich bin mir aber nicht sicher, ob das unter windoofs vernünftig funzt. andere möglichkeit: du startest einen überwachungsthread, der alle 5 sekunden aufwacht und den zeitpunkt des letzten empfangenen datenschnipsels checkt. ist z.b. nach 5s, trotz offener verbindung, nix gekommen macht der thread einfach den socket zu. dann kommt recv() auch mit SOCKET_ERROR zurück und alles wird gut.

-
Mit
selectund einem Timeout, sollte das auch machbar sein.
-
TCP keep alive timeouts sind viel zu lange, als dass man damit was anfangen könnte.
5s dagegen sind IMO viel zu kurz, als dass man davon ausgehen könnte, dass die gegenstelle weg ist.