C++ / Web packets

02/05/2012 14:23 Lawliet#1
Hallo,
Ich habe vor ein paar Tagen angefangen auf C++ umzusteigen.
Aktuell versuche ich eines meiner alten Autoit Programme in C++ neu zu schreiben. Dabei muss ich mich unter anderem auf einer Seite einloggen, html Code bearbeiten usw.
Gibts dafür eine gute Lib oder ein Tutorial, wie ich das über TCP löse?

MfG Lawliet!
02/05/2012 15:02 Rainvair#2
[Only registered and activated users can see links. Click Here To Register...]

Mit cURL solltest du dir den Großteil der Arbeit sparen können.
Falls du die Seite grafisch darstellen willst würde ich dir QT oder wxwidgets empfehlen. [Only registered and activated users can see links. Click Here To Register...]
02/05/2012 15:04 ms​#3
HTTP geht ziemlich einfach mit [Only registered and activated users can see links. Click Here To Register...]. Die HTML-Seiten kannst du mit einer Regex-lib wie z.B. mit der von [Only registered and activated users can see links. Click Here To Register...] parsen.
02/05/2012 15:55 käsekuchen11elf#4
Wenn du nen low-level ansatz suchst: es gibt unter windows und linux Socket interfaces, die man für so was benutzen kann.
02/05/2012 16:18 .Infinite#5
Hier gibt es ein relativ gutes Tutorial zu winsocks:

[Only registered and activated users can see links. Click Here To Register...]
02/05/2012 16:52 Lawliet#6
Wenn ich dabei auch möglichst viel lernen will, was sollte ich dann nutzen?
Ich will nur den html code als string zurück bekommen und eine login session aufrecht erhalten.
02/05/2012 17:41 .Infinite#7
Wenn du was lernen willst und das Programm nur auf Windowsrechnern laufen muss, machs mit winsocks und schreib dir eine schöne, handliche Klasse, die du immer wieder verwenden kannst und die auf deine Bedürfnisse zugeschnitten ist.
02/07/2012 23:38 MrSm!th#8
Winsocks sind fast identisch auf Linux aufgebaut.

Du könntest auch die WinInet Api nutzen, die übernimmt schon den ganzen Http-Protokoll-Scheiß, aber auch nicht mehr (vermutlich eher weniger), als Autoit übernimmt :p
Von daher solltest du mehr als mit Autoit lernen.
02/08/2012 09:09 käsekuchen11elf#9
Quote:
Originally Posted by MrSm!th View Post
Winsocks sind fast identisch auf Linux aufgebaut.
nicht ganz. die linux sockets verhalten sich wie FilePointer, wohingegen die winsock library auf HANDLES arbeitet. kleiner, aber gemeiner unterschied :)
zudem heißen einige der Funktionen leicht anders.
02/08/2012 20:38 Lawliet#10
Also ich habs jetzt mit Winsock geschafft, bis auf Recv() :/
Ich bekomms einfach nicht hin bis zum Ende zu lesen und dann die Schleife zu breaken.
Recv darf ja nie nichts empfangen, da man sonst ewig an der Stelle hängt. Wie empfange ich nur den HtmlHeader, damit ich die restliche Länge des Files aus "Content-Length" lesen kann?
02/08/2012 21:37 .Infinite#11
So zum Beispiel sollte es gehen

Code:
string XYZ::Receive()
{
	string response;
	char ReceivedBytes[256];
	int BytesReceived = 1;
	while(BytesReceived > 0)
	{
		BytesReceived = recv(Socket, ReceivedBytes, sizeof(ReceivedBytes), 0);
		response.append(ReceivedBytes, BytesReceived);
	}
	return response;
};
Es fehlt eventuell noch ein bisschen Fehlerbehandlung aber funktionieren tut es.

Der Header ist vom Content durch ein "\r\n\r\n" getrennt. Einfach nen break setzen, wenn du diese Bytefolge empfangen hast. Dann haste nur den Header. Aber wozu nur den Header empfangen, wenn man die ganze Seite haben kann? ;)
02/11/2012 11:56 Lawliet#12
Quote:
Originally Posted by .Infinite View Post
So zum Beispiel sollte es gehen

Code:
string XYZ::Receive()
{
	string response;
	char ReceivedBytes[256];
	int BytesReceived = 1;
	while(BytesReceived > 0)
	{
		BytesReceived = recv(Socket, ReceivedBytes, sizeof(ReceivedBytes), 0);
		response.append(ReceivedBytes, BytesReceived);
	}
	return response;
};
Es fehlt eventuell noch ein bisschen Fehlerbehandlung aber funktionieren tut es.

Der Header ist vom Content durch ein "\r\n\r\n" getrennt. Einfach nen break setzen, wenn du diese Bytefolge empfangen hast. Dann haste nur den Header. Aber wozu nur den Header empfangen, wenn man die ganze Seite haben kann? ;)
Nein, da ja recv niemals 0 zurückgibt.
02/11/2012 12:46 MrSm!th#13
Doch, wenn die Verbindung geschlossen wurde, dann hast du die ganze Seite.

Er sagte doch schon, du sollst selbst aus der Schleife austreten, wenn du die Bytefolge erhalten hast! Das war noch kein fertiger Code.
Du müsstest nun in der Schleife prüfen, ob die Bytefolge in der Response ist und falls ja, trittst du aus der Schleife aus und hast den Header.
Aber warum austreten? Kannst doch einfach direkt in der Schleife die Size auslesen und dann dementsprechend weiter verfahren. Oder geht es dir gar nicht darum, zu wissen, wie viel du noch herunterladen musst?

@Infinite:

1. Ist doch seine Sache?! Wenn der den Rest nunmal nicht will, warum Kapazitäten verschwenden?
2. Wenn du zb. vorher die Größe der Seite haben willst, damit du weißt, wann du die Schleife abbrechen kannst, weil sie erreicht ist. Das ist hilfreich, wenn du dem Server nicht sagst, dass du nach Beenden des Ladevorgangs willst, dass die Verbindung geschlossen wird. Dann musst du ja irgendwie herausfinden, dass du die Seite schon geladen hast, recv gibt dann ja kein 0 zurück.
02/11/2012 13:58 .Infinite#14
Quote:
Das ist hilfreich, wenn du dem Server nicht sagst, dass du nach Beenden des Ladevorgangs willst, dass die Verbindung geschlossen wird.
Einfach im Header des gesendeten Pakets
Code:
Connection: close
statt
Code:
Connection: keep-alive
schreiben.

Der Server weiß, dass die Verbindung geschlossen werden soll und recv() gibt 0 zurück. Alles bestens ;)
Mir fällt spontan kein Grund ein, aus dem man das vermeiden sollte...
02/11/2012 14:05 MrSm!th#15
Quote:
Originally Posted by .Infinite View Post
Einfach im Header des gesendeten Pakets
Code:
Connection: close
statt
Code:
Connection: keep-alive
schreiben.

Der Server weiß, dass die Verbindung geschlossen werden soll und recv() gibt 0 zurück. Alles bestens ;)
Mir fällt spontan kein Grund ein, aus dem man das vermeiden sollte...
Und wenn du lesen könntest, wüsstest du, dass ich sagte, dass sein Vorhaben nötig ist, WENN MAN DAS GERADE NICHT WILL!

Ein Grund wäre die Performance. Bei großen Anfragen kostet es viel Zeit, die Verbindung jedes mal neu aufzubauen.