Winsock http-get Frage
-
-
Vielen Dank für die Antwort. Hab mir jetzt mal ein Stück Code zu http het zusammengebastelt, leider funktioniert es nicht.
Hier der Code-Schnipsel
BYTE cServer_Address[256] = "www.familientreffen2005.de"; BYTE cFile_Name[256] ="/Test.txt"; char sen[100]; long rc; SOCKET s; SOCKADDR_IN addr; WSADATA wsa; //Das Klappt rc = WSAStartup(MAKEWORD(2,0),&wsa); HOSTENT* he;´ //Das Klappt auch he=gethostbyname((const char*)cServer_Address); if (he != NULL) { int i = 0; while(he->h_addr_list[i]) { addr.sin_addr.s_addr=*((long*)he->h_addr_list[i++]); } } if((addr.sin_addr.s_addr=inet_addr((const char*)cServer_Address))==INADDR_NONE) strncpy((char*)&addr.sin_addr.s_addr,he->h_addr,4); else addr.sin_addr.s_addr=inet_addr((char*) cServer_Address); if(addr.sin_addr.s_addr==INADDR_NONE) { return false; } //Das Klappt if(s=socket(AF_INET,SOCK_STREAM,0) == INVALID_SOCKET) { return false; } memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(80); // Hier bekomme ich für rc immer den Wert -1 also SOCKET_ERROR. Wenn ich // bei cServer_Address statt der Domain gleich die Server Adresse eingeben // klappt connect aber bei recv weiter unten erhalte ich dann -1 rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); string FileName = "GET " + (string) (char*) cFile_Name + " HTTP/1.1\r\n"; char* in_buf; string Dir = ""; if(rc!=SOCKET_ERROR) { strcpy(sen,FileName.c_str()); send(s,sen,100,0); send(s, "Connection: Keep-Alive\r\n", 100, 0); send(s, "User-Agent: DeinClient\r\n", 100, 0); send(s, "Host: www.tiscali.de:80\r\n", 100, 0); send(s, "Accept: */*\r\n\r\n", 100, 0); rc = recv(s, in_buf, sizeof(in_buf), 0);Wie gesagt wenn ich zuerst versuche mit gehostbyname die Domain aufzulösen erhalte ich schon bei connect für rc = -1, wenn ich bei cServer_Address gleich die ip des Servers eingebe, klappt connect aber dafür erhalte ich später bei recv für rc = - 1. Kann mir jemand sagen was ich falsch mache?
-
memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(80); rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR));memset <= Du leerst die komplette Struktur.
sin_family <= Du setzt sin_family
sin_port <= Du setzt den Port
sin_addr <= Du setzt nicht die Ziel-IP ?!
connect() <= Du verbindest dich mit 0.0.0.0:80 ?!
-
Danke für die Hilfe! Das war wirklich ein doofer Fehler. Ich hab den Source jetzt geändert und zwar so:
BYTE cServer_Address[256] = "www.familien-treffen.net"; BYTE cFile_Name[256] ="/Test.txt"; char sen[100]; long rc; SOCKET s; SOCKADDR_IN addr; WSADATA wsa; rc = WSAStartup(MAKEWORD(2,0),&wsa); HOSTENT* he; memset(&addr,0,sizeof(SOCKADDR_IN)); addr.sin_family=AF_INET; addr.sin_port=htons(80); // Host auflösen he=gethostbyname((const char*)cServer_Address); if((addr.sin_addr.S_un.S_addr=inet_addr((const char*)cServer_Address))==INADDR_NONE) { //Ip einlesen strncpy((char*)&addr.sin_addr.S_un.S_addr,he->h_addr,4); } else { addr.sin_addr.S_un.S_addr =inet_addr((char*) cServer_Address); } //IP jetzt richtig? if(addr.sin_addr.S_un.S_addr==INADDR_NONE) { return false; } //Dann verbinden rc=connect(s,(SOCKADDR*)&addr,sizeof(SOCKADDR)); string FileName = "GET " + (string) (char*) cFile_Name + " HTTP/1.1\r\n"; //rc ergibt immer noch -1, jetzt mit der Fehlermeldung 10038 = Operation on Non-Socket int Error = WSAGetLastError();Allerdings bekomme ich bei connect immer noch -1 und GetLastError liefert den fehlercode 10038 = Operation on Non-Socket. Hat jemand eine Ahnung wo jetzt der Fehler liegt? Schau nicht so ganz durch

-
Jetzt sehe ich vor dem connect() nirgendswo mehr dieses:
s=socket(AF_INET,SOCK_STREAM,0);
-
Eine interessante Seite neben dem c-worker tutorial ist übrigens auch diese:
http://rcswww.urz.tu-dresden.de/~s3060864/kompendium/
- nur mal so nebenbei erwähnt.
-
Danke für die Hilfe
Ich habe es jetzt hingekriegt mich zu verbinden und eine korrekte http get-Anfrage zu stellen, aller Anfang ist eben schwer 
Allerdings hab ich jetzt das Problem, das die Daten offenbar nicht korrekt übertragen werden. Es kommt zu erst der normale Server-Header und dann hab ich zum testen mit http get mal versucht eine Datei zu laden, die auf dem Webspace liegt. Es handelt sich dabei um eine Zip Datein die 98 kb groß ist: Hier ist der Codeausschnitt:string Buffer; string Dir = ""; int len = sprintf(sen, "GET /Test.zip HTTP/1.1\r\n" "Connection: Keep-Alive\r\n" "User-Agent: DeinClient\r\n" "Host: www.lovehits.net:80\r\n" "Accept: */*\r\n\r\n"); string Uebertrag = ""; if(rc!=SOCKET_ERROR) { for (int i = 0; i < len; i += rc) { rc = send(s, sen + i, len - i, 0); } try { int i = 0; while (rc > 0) { rc = recv(s, in_buf, sizeof(in_buf), 0); //Dateigröße 98 kb -> Nach dem Empfangen sind im String aber nur 3 kb. Uebertrag += in_buf; // Zähler steht nach dem Empfangen auf 103168, scheint also richtig zu sein. i += 256; } } catch(...) { }Von der Datei stehen nachher aber nur 3 kb im String. Weil in_buf ja eine Größe von 256 hat, dachte ich ich zähle mal mit ob das runterladen evtl zu früh abgebrochen wird, aber der Zähler i steht nachher bei 103168, käme bei einer Dateigröße von 98 kb ja hin oder? Aber wieso stehen im String nur 3 kb?
-
in_buf ist ein char* denk ich mal, oder?
der wird bei 0 terminiert, wenn du den an den std::string anhängen möchtest musst du append() benutzten (glaub ich) und auch die länge des anzuhängenden stücks angebenbei rc = recv(...) steht in rc die empfangenen bytes die du zu deiner countervriable hinzuzählen musst
-
Ich habs jetzt mal mit append probiert:
while (rc > 0) { rc = recv(s, in_buf, sizeof(in_buf), 0); //Dateigröße 98 kb -> Nach dem Empfangen sind im String jetzt 4 kb, ist schon ein kb mehr als bei ersten Versuch ;) Uebertrag.append(in_buf, sizeof(in_buf)); // Zähler steht nach dem Empfangen auf 103168, scheint also richtig zu sein. i += rc; }Jetzt sind im String nach dem Empfang 4075 Zeichen (also 4 kb). i steht nach dem EMpfangen übrigens immer noch auf einem Wert über 100000, es scheint also wirklich die ganze Datei empfangen zu werden, aber in den String werden nur 4 kb reingeschrieben. Ich möchte die Datei einfach empfangen, die Http-Header rausfiltern und dann das ganze in eine neue Datei speichern auf der Festplatte.
-
while (rc > 0) { rc = recv(s, in_buf, sizeof(in_buf), 0); if( rc < 1 ) break; //Dateigröße 98 kb -> Nach dem Empfangen sind im String jetzt 4 kb, ist schon ein kb mehr als bei ersten Versuch ;) Uebertrag.append(in_buf, rc); // Zähler steht nach dem Empfangen auf 103168, scheint also richtig zu sein. i += rc; }theoretisch müsste das so gehen... glaub ich...
-
Also mit rc statt sizeof(in_buf) hatte ichs auch schon probiert, mit dem gleichen Ergebnis - wieder nur 4 kb im String. Weiss langsam echt nicht mehr was falsch ist.
-
Okay habe das Problem jetzt glaub ich etwas näher eingekreist. Ich hab mir mal angeschaut, was in dem Buffer in_buf steht und was dann wirklich in den String kopiert wird. Der Buffer hat an vielen Stellen das zeichen 0 stehen (''), das natürlich nicht mit in den String kopiert wird. Deshalb ist das Ergebnis das im String steht nachher deutlich kleiner als der Ursprung der eingelesen wurde. Deshalb zwei Fragen. Warum steht an sovielen Stellen 0 = '' im Buffer(oder vielleicht noch andere Zeichen die nicht mitkopiert werden?? Sind ja insgesamt 98kb -> 3kb), ist das normal wenn ich eine Datei über http get einlese? Wie kann ich alle Zeichen in den string übertragen, damit ich die Datei wieder 1 zu 1 auf die Festplatte schreiben kann und eine komplette lauffähige Datei erhalte?