Socket und Co
-
Hiho,
hab mich mal an die Socketprogrammierung in Cpp gewagt.
So weit alles kein Ding. Versteh die ganzen Zusammenhänge, Funktionen, Bla!
Komme mit allem klar. Außer mit einem.
Ich dachte mir mal: so... connecten wa den neuen Client mal auf google.de:80
.. kurz google.de gepingt, IP in den Client gehackt und den Port auf 80 gestellt.
Zu Anfang vergaß ich, dass zuerst der Client an Port 80 schicken muss, ehe der ganze HTML Quatsch kommt.
Anschließend hab ich ne Sendmessage eingebunden.
Inhalt:
GET ./index.html HTTP1.1Vorher natürlich mit telnet getestet. Klappte dort prima.
Jedoch bekam ich nach dem erfolgreichen der Nachricht kein Reply.
Habs anschließend "für Dumme" auf
GET ./ HTTP1.1abgeändert, jedoch schickt er genau so wie beim ersten Versuch nur die Message erfolgreich raus.
Anschließend wartet er vergeblich auf eine Antwort. D.h. die Antwort ist nichtmal nichts, sondern es existiert keine.
Hier mal mein Codegedöhns ...
#include "stdafx.h" #include <iostream> #include <string> #include <winsock2.h> #include <windows.h> using namespace std; int startWinsock( void ); int main( void ) { long getWinsock; SOCKET mySocket; int SocketConnect; int SocketSend; int SocketReceive; SOCKADDR_IN SocketAddress; char SocketMessage[] = "GET ./ HTTP1.1"; char SocketReceive_Buffer[256]; unsigned short addrPort = 80; char *addrIP = "217.72.195.42"; getWinsock = startWinsock(); if( getWinsock == 0 ) { cout<<"Winsock wurde erfolgreich gestartet.\n"; mySocket = socket( AF_INET, SOCK_STREAM, 0 ); if( mySocket == INVALID_SOCKET ) cout<<"Fehler beim Erstellen des Sockets.\nFehlercode: "<<WSAGetLastError()<<"\n"; else { cout<<"Socket wurde erfolgreich erstellt.\n"; memset( &SocketAddress, 0, sizeof( SocketAddress ) ); SocketAddress.sin_family = AF_INET; SocketAddress.sin_port = htons( addrPort ); SocketAddress.sin_addr.s_addr = inet_addr( addrIP ); SocketConnect = connect( mySocket, (SOCKADDR*)&SocketAddress, sizeof( SocketAddress ) ); if( SocketConnect != SOCKET_ERROR ) { cout<<"Verbindung wurde erfolgreich hergestellt.\n"; cout<<"Sende Nachricht '"<<SocketMessage<<"' ...\n"; SocketSend = send( mySocket, SocketMessage, strlen( SocketMessage ), 0 ); if( SocketSend != SOCKET_ERROR ) { cout<<"Nachricht wurde erfolgreich gesendet.\n"<<SocketSend<<" Bytes uebertragen.\n"; cout<<"Warten auf Nachricht ...\n"; SocketReceive = recv( mySocket, SocketReceive_Buffer, 256, 0 ); if( SocketReceive == SOCKET_ERROR ) cout<<"Fehler beim Warten auf Nachricht.\nFehlercode: "<<WSAGetLastError()<<"\n"; else if ( SocketReceive == 0 ) cout<<"Die Gegenseite hat die Verbindung beendet.\n"; else { cout<<"Daten empfangen.\n"<<SocketReceive<<" Bytes wurden von der Gegenseite empfangen.\n"; cout<<"Daten: "<<SocketReceive_Buffer<<"\n"; } } else cout<<"Fehler beim Senden der Nachricht.\nFehlercode: "<<WSAGetLastError()<<"\n"; } else cout<<"Fehler beim Verbinden zu Adresse "<<addrIP<<":"<<addrPort<<".\nFehlercode: "<<WSAGetLastError()<<"\n"; } } else cout<<"Fehler beim Starten von Winsock.\nFehlercode: "<<getWinsock<<"\n"; cout<<"\n"; system( "pause" ); return 0; } int startWinsock( void ) { WSADATA wsa; return WSAStartup( MAKEWORD( 2, 0 ), &wsa ); }Evtl. hat ja jemand die passende Lösung für mich.
Würde mich auf jeden Fall schon mal riesig über ne Antwort freuen.
Danke!
-
1. Fehler, falsches Forum. Ich weiss echt nicht, wie ihr immer WINsock mit C++ in Verbindung bringen könnt und nicht mit WinAPI.
2. Fehler, das HTTP Protokoll verlangt ein anderes Format!
unlimieD.paSe schrieb:
GET ./ HTTP1.1Das ist keine gültige HTTP/1.1 Anfrage. Richtig wäre:
GET / HTTP/1.1 Host: www.google.deOder als C++ String:
"GET / HTTP/1.1\r\nHost: www.google.de\r\n\r\n"
Davon ist alles wichtig, auch die ganzen neuen Zeilen sind entscheidend!3. Fehler, Angabe der TCP Verbindung vergessen:
mySocket = socket( AF_INET, SOCK_STREAM, 0 );
Sollte lauten:
mySocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );4. Fehler, die IP Adresse. Die kann extrem varieren und sollte deshalb immer neu aufgelöst werden. Am besten mit dieser Funktion:
getaddrinfo
Auch darauf schauen, dass die IP und der angegebene Host im HTTP-Get übereinstimmen! Google hat sogar unterschiedliche IPs für www.google.de und google.de!5. Warnung, du benutzt teilweise deprecated Funktionen. Winsocket Funktionen:
http://msdn.microsoft.com/en-us/library/ms741394(VS.85).aspxWenn du das alles einhälst, dann funktioniert es. Bei mir kam jedenfalls ein OK zurück mit Inhalt.
Ich möchte aber noch darauf hinweisen, dass Google chunked überträgt. Also Google sendet mehrere "Pakete" an Daten. Man erfährt die Menge, welche übermittelt wird, durch eine Hexadezimalzahl, welche auch übermittelt wird. Ich empfehle dazu das RFC 2616 zu lesen. Die Sache mit dem Chunked steht im Kapitel 3.6, bzw. 3.6.1. Es empfiehlt sich aber durchaus auch ca. die ersten 40 Seiten zu lesen. Der Rest ist mehr Nachschlagewerk.Grüssli
-
SocketReceive_Buffer ist außerdem nicht null-terminiert.
Das gibt bei cout wohl nen seltsamen output.
-
Dieser Thread wurde von Moderator/in evilissimo aus dem Forum C++ in das Forum WinAPI verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.