[C++] Webseiten Inhalt über Socket empfangen
-
Hallo,
Ich bin grade am verzweifeln, mein Problem ist das ich über ein Socket den Inhalt von einer Webseite bekommen möchte aber ich leider nur den Header der Webseite erhalte. Leider ist es mir nicht möglich Curl oder ähnliche Libs zu verwenden da ich die SDK der Playstation 3 nutze.
Das ist mein code
https://pastebin.com/raw/mzsUjBpaDas ist die Seite von der ich in diesen Fall "Hello" bekommen möchte:
http://pastebin.com/raw/xNCb6hrSUnd das ist die Antwort die ich erhalte:
HTTP/1.1 200 OK
Date: Sun, 23 Jul 2017 23:40:25 GMT
Content-Type: text/plain; charset=utf-8
Transfer-Encoding: chunked
Conn
-
Nach den ersten empfangenen Bytes, wird die Funktion verlassen, obwohl noch nicht die ganze Antwort empfangen wurde.
while (recv(Socket, bufferReturn, 10000, 0) > 0) { return bufferReturn; }
Du musst die empfangenen Bytes müssen noch zusammensetzen. Das kannst du indem du sie in ein Buffer kopierst (oder durch
recv(..)
an die richtige Stelle schreiben lässt).Übrigens setzt dieser Code voraus, dass die Verbindung von der Gegenstelle geschlossen wird.
-
Hey theta, danke für die schnelle Antwort. Ich habe es jetzt so probiert
char* message; while (recv(HTTPSocket, HTTPbufferReturn, 10000, 0) > 0) { for (int i = 0; i < sizeof(HTTPbufferReturn) - 1; i++){ message += HTTPbufferReturn[i-1]; } } return message;
Aber leider bekomme ich so nur ein Fehler. Kannst du mir vielleicht weiterhelfen? PS.: Die Verbindung wird zu 100% vom Server geschlossen. Aber zu Sicherheit habe ich in die Anfrage noch "\r\nConnection: close" eingebaut.
-
DerRuedi schrieb:
Hey theta, danke für die schnelle Antwort. Ich habe es jetzt so probiert
char* message; while (recv(HTTPSocket, HTTPbufferReturn, 10000, 0) > 0) { for (int i = 0; i < sizeof(HTTPbufferReturn) - 1; i++){ message += HTTPbufferReturn[i-1]; } } return message;
Aber leider bekomme ich so nur ein Fehler. Kannst du mir vielleicht weiterhelfen? PS.: Die Verbindung wird zu 100% vom Server geschlossen. Aber zu Sicherheit habe ich in die Anfrage noch "\r\nConnection: close" eingebaut.
Probier mal so:
int offset = 0; int packetsize; while (packetsize = recv(HTTPSocket, HTTPbufferReturn+offset, 10000-offset, 0) > 0) offset += packetsize;
Danach sollte alles in HTTPbufferReturn stehen.
^^ habs nicht ausprobiert, aber so im Prinzip geht das.
-
Leider klappt es immer noch nicht.
So sieht aktuell der Code aus:
#define HTTPSERVER_PORT htons(80) int HTTPSocket; struct hostent *HTTPHost; struct sockaddr_in HTTPSocketAddress; char HTTPbufferReturn[10000]; char HTTPRequestBuffer[2000]; char* HTTPRequest(char* URL, char* Key) { HTTPHost = gethostbyname(URL); HTTPSocketAddress.sin_addr.s_addr = *((unsigned long*)HTTPHost->h_addr); HTTPSocketAddress.sin_family = AF_INET; HTTPSocketAddress.sin_port = HTTPSERVER_PORT; HTTPSocket = socket(AF_INET, SOCK_STREAM, 0); if (connect(HTTPSocket, (struct sockaddr *)&HTTPSocketAddress, sizeof(HTTPSocketAddress)) != 0) { return "CONNECTION ERROR"; } strcpy(HTTPRequestBuffer, "GET /"); strcat(HTTPRequestBuffer, Key); strcat(HTTPRequestBuffer, " HTTP/1.1"); strcat(HTTPRequestBuffer, "\r\nHOST: "); strcat(HTTPRequestBuffer, URL); strcat(HTTPRequestBuffer, "\r\nConnection: close"); strcat(HTTPRequestBuffer, "\r\n\r\n"); send(HTTPSocket, HTTPRequestBuffer, strlen(HTTPRequestBuffer), 0); int offset = 0; int packetsize; while (packetsize = recv(HTTPSocket, HTTPbufferReturn+offset, 10000-offset, 0) > 0) offset += packetsize; return HTTPbufferReturn; socketclose(HTTPSocket); }
Und das gibt er mir aus:
HTTP/1.1 200 OK Date: Mon, 24 Jul 2017 10:13:13 GMT Server: Apache/2.4.18 (Ubuntu) Content-Length: 8 Content-Type: text/htm
-
Was soll den der Spaß mit dem Offset? Wenn ich die Doku auf die Schnelle richtig verstehe ist das komplett unnötig.
while (recv(HTTPSocket, HTTPbufferReturn, sizeof(HTTPbufferReturn), 0) > 0);
sollte das machen, was du möchtest. Solange du nicht mehr als 10000 Zeichen empfangen möchtest.
Ansonsten hat Google noch das hier ausgespuckt
https://www.c-plusplus.net/forum/224651-fullP.S. Du returnst bevor du socketclose aufrufst => Socket wird nicht geshclossen.
Edit: je länger ich drüber nachdenke desto unsicherer bin ich mir mit dem Buffer....
-
Hey Schlangenmensch,
Ich habe den Code jetzt mal so abgeändert:
#define HTTPSERVER_PORT htons(80) int HTTPSocket; struct hostent *HTTPHost; struct sockaddr_in HTTPSocketAddress; char HTTPbufferReturn[10000]; char HTTPRequestBuffer[2000]; char* HTTPRequest(char* URL, char* Key) { HTTPHost = gethostbyname(URL); HTTPSocketAddress.sin_addr.s_addr = *((unsigned long*)HTTPHost->h_addr); HTTPSocketAddress.sin_family = AF_INET; HTTPSocketAddress.sin_port = HTTPSERVER_PORT; HTTPSocket = socket(AF_INET, SOCK_STREAM, 0); if (connect(HTTPSocket, (struct sockaddr *)&HTTPSocketAddress, sizeof(HTTPSocketAddress)) != 0) { return "CONNECTION ERROR"; } strcpy(HTTPRequestBuffer, "GET /"); strcat(HTTPRequestBuffer, Key); strcat(HTTPRequestBuffer, " HTTP/1.1"); strcat(HTTPRequestBuffer, "\r\nHOST: "); strcat(HTTPRequestBuffer, URL); strcat(HTTPRequestBuffer, "\r\nConnection: close"); strcat(HTTPRequestBuffer, "\r\n\r\n"); send(HTTPSocket, HTTPRequestBuffer, strlen(HTTPRequestBuffer), 0); while (recv(HTTPSocket, HTTPbufferReturn, sizeof(HTTPbufferReturn), 0) > 0); socketclose(HTTPSocket); return HTTPbufferReturn; }
Aber trotzdem bekomme ich nur das zurück:
HTTP/1.1 200 OK Date: Mon, 24 Jul 2017 10:30:52 GMT Server: Apache/2.4.18 (Ubuntu) Content-Length: 8 Connection: close Con
-
@Schlangenmensch+DerRuedi: Der Offset ist nötig, um nicht bei jedem recv(..) Aufruf den schon empfangenen Teil zu überschreiben. Alternativ könnte man natürlich die Daten umkopieren und auf diese Weise sammeln.
-
Schlangenmensch schrieb:
Was soll den der Spaß mit dem Offset?
Das ist, damit die Daten des nächsten recv an den Buffer angehängt werden.
Hab das aus dem Kopf geschrieben. Kann natürlich Fehler beinhalten. Aber prinzipiell geht das.
-
Aber trotz das ich diesen Code verwende:
int offset = 0; int packetsize; while (packetsize = recv(HTTPSocket, HTTPbufferReturn+offset, 10000-offset, 0) > 0) offset += packetsize;
Bekomme ich nur die Antwort:
HTTP/1.1 200 OK Date: Mon, 24 Jul 2017 10:38:53 GMT Server: Apache/2.4.18 (Ubuntu) Content-Length: 8 Connection: close Con
-
Jetzt hab ich das mit dem Offset auch
@Der Rudi: Wie rufst du die Funktion denn auf, wie machst du deine Ausgabe?
Wird die While Schleife beendet weil resc 0 zurück gibt, oder wird eventuell ein Fehler zurück gegeben (Rückgabe < 0)
-
DerRuedi schrieb:
Aber trotz das ich diesen Code verwende:
int offset = 0; int packetsize; while (packetsize = recv(HTTPSocket, HTTPbufferReturn+offset, 10000-offset, 0) > 0) offset += packetsize;
Bekomme ich nur die Antwort:
HTTP/1.1 200 OK Date: Mon, 24 Jul 2017 10:38:53 GMT Server: Apache/2.4.18 (Ubuntu) Content-Length: 8 Connection: close Con
Du solltest danch HTTPbufferReturn nicht mehr verändern, also quasi nach der while-schleife den inhalt von HTTPbufferReturn als gegeben hinnehmen.
-
Ich habe das Problem (die Probleme) gefunden. Das erste was die Art und weiße wie ich die Bytes empfangen habe. Was durch @Fricky667 behoben werden konnte.
Fix:
int offset = 0; int packetsize; while (packetsize = recv(HTTPSocket, HTTPbufferReturn+offset, 10000-offset, 0) > 0) offset += packetsize;
Und daran wie ich es ausgeben habe. Ich hatte printf verwendet, was mir aber nicht alles dargestellt hat.
-
DerRuedi schrieb:
Ich habe das Problem (die Probleme) gefunden. Das erste was die Art und weiße wie ich die Bytes empfangen habe. Was durch @Fricky667 behoben werden konnte.
Danke, Bro. Ich freue ich mich, dass ich dir helfen konnte.