Socket geschlossen nach recv
-
Ich würde dir empfehlen, eine Bibliothek dafür zu verwenden. Da wäre z.B. curl oder für Sockets alleine boost::asio zu nennen. Die Frickelei mit der C-API ist halt ziemlich fehleranfällig.
-
c++-- schrieb:
1. Wird der Socket nach jedem send() & recv() geschlossen?
Nein.
c++-- schrieb:
2. Weshalb kann ich den weiten Request nicht durchführen.
Vermutlich trennt der Server die Verbindung. Das kannst du ja schon an der Bedingung der while-Schleife erkennen. recv() würde blockieren, wenn der Server die Verbindung nicht schließen würde.
c++-- schrieb:
3. Wie kann ich mehrere Requests durchführen, ohne den Socket immer wieder neu erstellen zu müssen?
Eventuell kannst du da am HTTP-Protokoll was drehen. connection: Keep-Alive oder so etwas in der Art. Aber Performanceeinbußen? Was willst du denn da programmieren?
Edit:
Ich sehe, du nutzt HTTP/1.1? Da sollten alle Verbindungen automatisch "keep-alive" sein. Doch deine Schleife wartet halt so lange, bis der Server die Verbindung schließt. Deshalb auch die Performanceprobleme bei neuen Verbindungen, du musst jedes mal auf ein ~15 Sekunden timeout warten. Nutze HTTP/1.0 oder überprüfe beim Empfangen ob du alles hast.
-
314159265358979 schrieb:
Ich würde dir empfehlen, eine Bibliothek dafür zu verwenden. Da wäre z.B. curl oder für Sockets alleine boost::asio zu nennen. Die Frickelei mit der C-API ist halt ziemlich fehleranfällig.
Hey,
sowas hatte ich mir auch schon überlegt, aber ich wollte mir eine eigene Klasse dazu schreiben.
Und jetzt einfach aufzuhören und eine fertige Bibliothek zu verwenden, bringt in meinen Augen wenig, da ich dann ja nichts dazu lerne und nicht weiß, wo/wie mein Fehler war.Gruß
-
cooky451 schrieb:
c++-- schrieb:
1. Wird der Socket nach jedem send() & recv() geschlossen?
Nein.
c++-- schrieb:
2. Weshalb kann ich den weiten Request nicht durchführen.
Vermutlich trennt der Server die Verbindung. Das kannst du ja schon an der Bedingung der while-Schleife erkennen. recv() würde blockieren, wenn der Server die Verbindung nicht schließen würde.
c++-- schrieb:
3. Wie kann ich mehrere Requests durchführen, ohne den Socket immer wieder neu erstellen zu müssen?
Eventuell kannst du da am HTTP-Protokoll was drehen. connection: Keep-Alive oder so etwas in der Art. Aber Performanceeinbußen? Was willst du denn da programmieren?
Danke für die Antworten!
Mir fällt da gerade ein, das im Antwort-Header sowas in der Art stand:
"Connection: close".Das würde mir 3tens beantworten. Das werde ich ausprobieren, Danke!
Wenn ich das Programm starte, dauert es erstmal so 3-5 Sekunden bevor der Request gesendet wird. Ich vermute dass WSA-Startup oder das connect() eine Weile braucht, weil dieser Nebeneffekt auch auftrat, als ich den Socket immer wieder neu erstellte.
Ich dachte noch nicht an ein konkretes Programm, sondern nur an eine Klasse, womit ich mir eine Website abholen kann, z.B. für einen HTTP-Chat.
Gruß
EDIT:
Connection
Der Connection-Header gibt an, ob die Verbindung nach der Transaktion aufrecht erhalten werden soll (keep-alive) oder nicht (close). Bei HTTP 1.0 werden Verbindungen standardmäßig geschlossen. Soll die Verbindung dennoch geöffnet bleiben, muss keep-alive als Wert angegeben werden. HTTP 1.1 verwendet jedoch persistente (aufrechterhaltende) Verbindungen. Damit die Verbindung hier dennoch geschlossen wird, muss close als Wert angegeben werden. Beispiel:
Connection: keep-alive
-
Der Teil, der wohl am längsten dauert, ist das resolven des Hosts. Ich würde das in eine eigene Funktion auslagern und im Konstruktor nur irgend ne IP-Klasse als Parameter akzeptieren.
-
314159265358979 schrieb:
Der Teil, der wohl am längsten dauert, ist das resolven des Hosts. Ich würde das in eine eigene Funktion auslagern und im Konstruktor nur irgend ne IP-Klasse als Parameter akzeptieren.
Ich übergebe in meinen Programm vorerst nur die IP-Adresse und nutze dann
inet_addr();Oder wie meinst du das jetzt?
GRuß
-
c++-- schrieb:
Oder wie meinst du das jetzt?
Er hat wohl an gethostbyname() und Konsorten gedacht, die eine DNS-Anfrage machen müssen.
Deinen Beitrag oben zu meinem Kommentar verstehe ich nicht ganz, hast du das Problem jetzt gelöst?
-
cooky451 schrieb:
c++-- schrieb:
Oder wie meinst du das jetzt?
Er hat wohl an gethostbyname() und Konsorten gedacht, die eine DNS-Anfrage machen müssen.
Deinen Beitrag oben zu meinem Kommentar verstehe ich nicht ganz, hast du das Problem jetzt gelöst?Nicht ganz

Also Antwort bekomme ich jetzt:
HTTP/1.1 200 OK Date: Thu, 08 Sep 2011 18:49:15 GMT Server: Apache/2.2.17 (Win32) PHP/5.3.5 X-Powered-By: PHP/5.3.5 Expires: Mon, 26 Jul 1997 05:00:00 GMT Last-Modified: Thu, 08 Sep 2011 18:49:15 GMT Cache-Control: no-store, no-cache, must-revalidate Cache-Control: post-check=0, pre-check=0 Pragma: no-cache Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: text/htmlJedoch wird das 2te HTTP-Request dann wieder nicht ausgeführt

Noch eine Idee?
GRuß
-
c++-- schrieb:
Noch eine Idee?
Nein, aber meine alten Ideen gelten weiterhin. Solange du eine Anfrage auf HTTP/1.1 machst, wird die Verbindung wohl am Leben gehalten. Da deine Schleife solange empfängt, bis die Verbindung geschlossen wird, musst du jedes Mal auf das Timeout warten.
Vermutlich ist die beste Lösung für dich einfach HTTP/1.0 zu nutzen. Da kannst du dann so wie jetzt empfangen.
-
cooky451 schrieb:
c++-- schrieb:
Noch eine Idee?
Nein, aber meine alten Ideen gelten weiterhin. Solange du eine Anfrage auf HTTP/1.1 machst, wird die Verbindung wohl am Leben gehalten. Da deine Schleife solange empfängt, bis die Verbindung geschlossen wird, musst du jedes Mal auf das Timeout warten.
Vermutlich ist die beste Lösung für dich einfach HTTP/1.0 zu nutzen. Da kannst du dann so wie jetzt empfangen.Ok. Ich habe jetzt die "Connection: close" gesetzt.
Damit ist nach einem Request schluss.Ich dachte mir jetzt, wenn die Verbindung geschlossen wird, dann müsste ich doch per "connect()" diese wieder aufbauen können und einen neuen Request absetzen, oder?
(void*) new HTTP_Request(this->sock,this->ip,this->page); connect(this->sock, reinterpret_cast<sockaddr*>(&this->service), sizeof(this->service)); (void*) new HTTP_Request(this->sock,this->ip,this->page);Jedoch funktioniert das genauso wenig?!
GRuß
-
Tja.. den Socket musst du wahrscheinlich schließen und dann einen neuen erstellen.
(Und nur so am Rande.. was ist das für eine komische Aktion mit dem "(void*) new HTTP_Request" und dem delete im Konstruktor? Bitte ändere das! :))
-
cooky451 schrieb:
Tja.. den Socket musst du wahrscheinlich schließen und dann einen neuen erstellen.
(Und nur so am Rande.. was ist das für eine komische Aktion mit dem "(void*) new HTTP_Request" und dem delete im Konstruktor? Bitte ändere das! :))
Ok.
Das habe ich bereits geändert.Gruß
-
So, es funktioniert jetzte!
Ich danke allen!
Gruß und schönes Wochenende noch.