Hallo, ich verwende die Bibliothek curl mit C++. curl: http://curl.haxx.se/libcurl/ chunked Verbindung: http://en.wikipedia.org/wiki/Chunked_transfer_encoding Das Programm läuft wie folgt ab. -Informationsabfrage von einem Server. -Empfangene Daten werden analysiert und curl wird konfiguriert. -In einem neuen Thread wird die Bibliothek curl ausgeführt. Dieser baut eine Verbindung (Session) mit dem Server aufgebaut. Anschließend erfolgt die Antwort als chunked Verbindung. Diese "blockiert" das Programm. Deswegen wird die chunked Verbindung in einem neuen Thread ausgeführt. Immer wenn Daten empfangen werden wird von curl eine "Writefunction" aufgerufen der die Daten zugeschoben werden. -Im Hauptthread erfolgt eine weitere Kommunikation mit dem Server. Dieser Teilt dem Server mit, welche Daten über die chunked Verbindung gesendet werden sollen. -Anschließend wird gewartet bis der Thread beendet wird (Unterbrechung des Datentransfers nach ca. 1,5h). -Das ganze beginnt von vorne. Zitat aus Wikipedia: "The last chunk is a zero-length chunk, with the chunk size coded as 0, but without any chunk data section." Problem: Wenn sich die Ip meines Rechners ändert, während die chunked Verbindung aktiv ist werden keine Daten mehr empfangen. Curl bekommt also nicht mit, dass die Verbindung beendet worden ist und der Thread läuft endlos weiter. Wie würdet Ihr das Problem lösen? Ich dachte darüber nach eine Zeitkontrolle einzubauen. Immer wenn Daten empfangen werden wird eine Variable gesetzt. Sobald über einen Zeitraum von n Sekunden keine Daten empfangen werden wird die Verbindung für tod erklärt und der Thread "zwangs"beendet. Dies kommt mir jedoch etwas unprofessionell vor. Habt Ihr Vorschläge, wie man das Problem geschickter lösen kann?
Ich hatte das mal (allerdings nicht mit Curl) durch das Senden von Keep-Alive-Chunks gelöst. War ne HTML-Anwendung, also konnte ich einfach jede Minute einen <!-- Kommentar --> über die Leitung jagen. Heute würd ich das zwar nicht mehr so machen, gibt ja inzwischen mit AJAX/WebSocket usw. bessere Möglichkeiten, aber funktioniert hats.
Ich verstehe nicht so ganz was das mit meinem Problem zu tun hat. Mein Problem ist ja, dass curl so lange wartet, bis eine Nachricht kommt. Aber die kommt nicht.
A. R. schrieb: > Wenn sich die Ip meines Rechners ändert, während die chunked Verbindung > aktiv ist werden keine Daten mehr empfangen Wie das? Sowas ist nun wirklich nicht vorgesehen, normalerweise sollte dann die Verbindung abbrechen. A. R. schrieb: > Ich dachte darüber nach eine Zeitkontrolle einzubauen. > Dies kommt mir jedoch etwas unprofessionell vor. Wieso? Das ist bei Netzverbindungen das Mittel der Wahl. A. R. schrieb: > Im Hauptthread erfolgt eine weitere Kommunikation mit dem Server. Du könntest eine Art "nop" Kommando definieren, spätestens beim Senden sollte auffallen falls die Gegenstelle nicht verfügbar ist.
>A. R. schrieb: >> Wenn sich die Ip meines Rechners ändert, während die chunked Verbindung >> aktiv ist werden keine Daten mehr empfangen >Wie das? Sowas ist nun wirklich nicht vorgesehen, normalerweise sollte >dann die Verbindung abbrechen. Eben genau das passiert nicht. Das ist mein Problem. Der Thread in dem die chunked Verbindung abläuft wird nicht beendet. Es kommt auch keine Fehlermeldung und nichts. Curl wartet einfach auf eine Antwort und es kommt nichts. Würde curl mit ner Fehlermeldung abbrechen wäre alles Super. Im Endeffekt starte ich eine Funktion und diese wird nie beendet. >A. R. schrieb: >> Ich dachte darüber nach eine Zeitkontrolle einzubauen. >> Dies kommt mir jedoch etwas unprofessionell vor. >Wieso? Das ist bei Netzverbindungen das Mittel der Wahl. Ja das wird bei Netzverbindungen öfterns gemacht. Deswegen frage ich ob das so in Ordnung ist oder ob es bessere Möglichkeiten gibt. Ich finde es etwas unprefessionell, da bei Zeitabfragen das debuggen extrem verschwert wird. Ich weiß auch nicht, wie ich die curl Verbindung abbrechen soll. Ich verwende Boost::Thread für Multithreads. Hierbei gibt es keinen close Befehl der den Thread zerstört. Zumindest ist mir keine bekannt. Curl kann ich auch nicht so ohne weiteres abbrechen. Ich kann es pausieren mehr auch nicht.
Gast
#2393786
A. R. schrieb: > Ich weiß auch nicht, wie ich die curl Verbindung abbrechen soll. > Ich verwende Boost::Thread für Multithreads. Hierbei gibt es keinen > close Befehl der den Thread zerstört. Zumindest ist mir keine bekannt. Ist auch besser so. Einen Thread einfach so rauszuschießen ist keine gute Idee, besonders wenn C++, Auto-variablen mit Konstruktoren, Mutexe usw. im Spiel sind. > Curl kann ich auch nicht so ohne weiteres abbrechen. Ich kann es > pausieren mehr auch nicht. Versuch mal die CURLOPT_PROGRESSFUNCTION zu setzen. Da solltest du bei jedem internen Curl-Poll/select-Schleifenlauf einen Aufruf kriegen, und kannst von dort aus komfortabel auf Timeout warten und auch die Verbindung/curl sauber beenden.
Schoneinmal vielen vielen Dank für die Information. Wenn ich das auf der Homepage von curl richtig interpretiere ist das genau das was ich suche. Damit hast du mir richtig geholfen.
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
Dort kann ich dann abfragen ob innerhalb der letzten n Sekunden eine Antwort vom Server kam (jede Sekunde kommt etwas, wenn auch nur ein keep alive). Wenn nicht kommt breche ich einfach curl ab. Somit muss ich dann auch nichts in der main verändern. [edit] Bitte /code/-Abschnitte manuell umbrechen, sie sind sonst nicht sinnvoll lesbar. -rufus
A. R. schrieb: > Ich verwende Boost::Thread für Multithreads. > Hierbei gibt es keinen > close Befehl der den Thread zerstört. Das üblich Pattern ist folgendes:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
Man darf dann natürlich nicht mit blockierenden Operationen arbeiten. Einige Threadbibliotheken unterstützen auch das Konzept des Thread interupts, sodass man einen Thread auch in blockierenden Operation aus dem Schlaf reißen kann:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.