WS2 Send Problem
-
Moin.
Ich wollte mir ne kleine Funktion basteln um einen HTTP Header an einen Server senden kann, und auch Daten vom Server empfangen kann.
Ich weiß ich könnte WinHTTP verwenden, jedoch möchte ich das nicht, ich will ja etwas lernen und deshalb, das ganze selbst Coden.
Soweit sogut, da ich es noch nicht hinbekomme, über die Domain an die IP - Adresse zu kommen, habe ich als Bsp. einfach mal den Google server genommen.
Bei Fehlern lasse ich mir unterschiedliche Werte zurückgeben, um festezustellen wo der Fehler entsteht.
Ein fehler entsht momentan immer bei Send. ich habe auch schon mit WSAGetLastError() den fehler ausgewertet, und ich bekomme den fehlercode 1411 zurück, welcher in der MSDN nicht Dokumentiert ist.
Sieht vllt einer auf anhieb den Fehler?
Achso, die nötigen Includes und die Lib´s sind natürlich gelinkt, ich Poste mal nur die 2 Funktionen, da es sonst etwas lang wird und ich in dem Forum hier nirgends Spoiler finde.
int TCPSendRecv (char *Buf, int Type, char *Host, char *Page, char *Post, char *Referer, char *Cookie) { char sendBuf[500] ; char RecvBuf[DEFAULT_BUFLEN] ; int iResult ; SOCKET s ; struct sockaddr_in Server ; struct hostent *HostIP = gethostbyname (Host) ; int recvbuflen = DEFAULT_BUFLEN ; SetPacket(Type, Host, Page, Referer, Post, Cookie, sendBuf) ; // Init an Socket s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ; // Set the Server Infos (muss mir noch klarwerden, wie das alles funktioniert !) Server.sin_family = AF_INET ; Server.sin_addr.s_addr = inet_addr ("74.125.79.147") ; // Zum Testen der Google Server Server.sin_port = htons (80) ; // Connect to Server iResult = connect (s, (SOCKADDR*) &Server, sizeof(Server)) ; if (iResult != 0) { WSACleanup (); return -1; } // Send to Server iResult = send (s, sendBuf, (int)strlen(sendBuf), 0) ; if (iResult != 0) { WSACleanup (); return -2; } // shutdown the connection since no more data will be sent iResult = shutdown(s, SD_SEND); if (iResult == SOCKET_ERROR) { closesocket(s); WSACleanup(); return -3; } // Receive until the peer closes the connection do { iResult = recv(s, RecvBuf, DEFAULT_BUFLEN, 0); if ( iResult <= 0 ){ closesocket(s); WSACleanup(); return -4; } } while( iResult > 0 ); strcpy (Buf, RecvBuf) ; // Close the Connection to the Server iResult = closesocket(s); if (iResult != 0) { WSACleanup (); return -5; } return 1 ; } void SetPacket(int Type, char *Host, char *Page, char *Referer, char *Post, char *Cookie, char *PacketBuf) { char buf[500] ; switch (Type) { case 1 : sprintf (buf, "GET %s HTTP/1.1 \r\n" "Host: %s \r\n" "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.4) Gecko/20100611 AskTbUT2V5/3.8.0.12304 Firefox/3.6.4 \r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 \r\n" "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 \r\n" "Keep-Alive: 115 \r\n" "Connection: keep-alive \r\n", Page, Host) ; if (strlen (Referer) > 1) sprintf (buf, "%sReferer: %s \r\n", buf, Referer) ; if (strlen (Cookie) > 1) sprintf (buf, "%sCookie: %s \r\n", buf, Cookie) ; // Abschließendes @crlf anhängen sprintf (buf, "%s\r\n", buf) ; break ; case 2 : sprintf (buf, "POST %s HTTP/1.1 \r\n" "Host: %s \r\n" "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.2.4) Gecko/20100611 AskTbUT2V5/3.8.0.12304 Firefox/3.6.4 \r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 \r\n" "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 \r\n" "Keep-Alive: 115 \r\n" "Connection: keep-alive \r\n", Page, Host) ; if (strlen (Referer) > 1) sprintf (buf, "%sReferer: %s \r\n", buf, Referer) ; if (strlen (Cookie) > 1) sprintf (buf, "%sCookie: %s \r\n", buf, Cookie) ; sprintf (buf, "%s" "Content-Type: application/x-www-form-urlencoded \r\n" "Content-Length: %i \r\n", buf, strlen (Post)) ; // Abschließendes @crlf und den Post anhängen sprintf (buf, "%s\r\n %s", buf, Post) ; break ; } strcpy(PacketBuf, buf) ; }mfg
-
Darter schrieb:
Ein fehler entsht momentan immer bei Send. ich habe auch schon mit WSAGetLastError() den fehler ausgewertet, und ich bekomme den fehlercode 1411 zurück, welcher in der MSDN nicht Dokumentiert ist.
Sieht vllt einer auf anhieb den Fehler?
Error code 1411 ist sehr wohl dokumentiert!
http://msdn.microsoft.com/en-us/library/ms681385(v=vs.85).aspxUnd etwas anderes! Ich würde den ganzen aufbau deines Codes hinterfragen!
Wenn du eine Net library brauchst die auf winsock 2.2 aufbaut und die dir die Arbeit ein wenig abnimmt, kannst du mich anschreiben. Bin da eine library am entwickeln, die denn ganzen IPV4 und IPV6 bereich abdeckt, und abstrahiert. Inkl. SocksV4 und V5 unterstützung sowie Http-proxy connections.
-
Hey.
Ok, ich hatte nur bei den speziellen Error codes für WSAGetLastError() gesucht.
Und was es damit aufsich aht :
ERROR_CLASS_DOES_NOT_EXIST
1411 (0x583)versteh ich auch nicht, welche Classe soll den bitteschön nicht existieren ?
-
Ohne mich jetzt in den hässlichen (sorry) Aufbau hinengelegt zu haben, möchte ich mal wissen wo du die Funktion http://msdn.microsoft.com/en-us/library/ms742213(v=vs.85).aspx aufrufst? Villeicht machst Du das ja, aber ich sehe es eben bei dem Schnipsel nicht!?
Ich weiss das es viel Arbeit ist! Aber beginne jetzt mit der umstrukturierung, sonnst wird es dich später ne menge Zeit kosten!!
-
Ich verst nicht genau, was ich umstruckturieren soll, gensu so sieht auch das bsp aus der masd aus, und WSAStartup () rufe ich ein einer Arte test func, die aufgerufen wurd wenn ich einen button drücke, ich kann ja mal das ganze sscript posten, aber ich denke nicht das das nötwendig ist.
-
Also wenn du einen Fehlercode unter 10000 bekommst, rufst du WSAGetLastError() zum falschen Zeitpunkt auf. Der Wert ist nur aussagekräftig nachdem send mit SOCKET_ERROR fehlgeschlagen ist.
-
So hatte ich die Func aufgerufen :
// Send to Server iResult = send (s, sendBuf, (int)strlen(sendBuf), 0) ; if (iResult != 0) { //WSACleanup (); return WSAGetLastError(); }
-
if (iResult == SOCKET_ERROR) {
-
Ich habe es genau so gemacht, wie aus dem bsp aus der msdn : http://msdn.microsoft.com/en-us/library/ms740149(v=vs.85).aspx
Und ich geh einfach mal davon aus, dass das was da steht auch richtig ist, oder etwa nicht ?
-
Jop, das Beispiel in der MSDN ist dann wohl fehlerhaft.
-
Wenn du nicht den ganzen Code posten willst kann ich dir nur pauschal sagen, alles Debuggen, Rückgabewerte prüfen etc.
Wenn man WSAGetLastError() und auch GetLastError() nicht richtig zu benützen weiss, kommt man schon mal auf die falsche Fährte.Bsp.
... ... l = recv(..,..,..,...); printf_s("%i\n",WSAGetLastError()); ... ...Du kannst hier nicht sagen oder wissen das dir WSAGetLastError() den Fehler von recv() liefert! Denn du weisst ja nicht ob auch wirklich die recv() fehlgeschlagen ist (ausser Du testest ob recv() dir SOCKET_ERROR oder 0 zurückgibt!, und dann kannst du WSAGetLastError() aufrufen um dir den spezifischen fehler auszugeben). Aber sonnst konnte ja WSAGetLastError() ein errorcode von einem anderen Aufruf der fehlgeschlagen ist zurück geben! Also da immer aufpassen.
Gleich ist es mit GetLastError().
Deshalb sollte man auch zum testen immer nur WSAGetLastError() in zusammenhang mit dem return Code der letzten Funktion benützen.
Also:
... ... l = recv(..,..,..,...); // Obwohl man hier recv() noch in einer Schleife aufrufen müsste. if(l == SOCKET_ERROR) { printf_s("%i\n",WSAGetLastError()); return 1; } ... ...Für ein erfahrenen Programmierer sicher klar. Doch für ein Anfänger manchmal sehr irreführend.