Sessions



  • string strRequestMessage = "GET " + this->m_strFolder + " HTTP/1.1\r\n Host: " + this->m_strServer + "\r\n\r\n";
    


  • sry
    werds jetzt mit \r\n probieren

    und du hast recht, ich meine sockets. weiß nich wo ich mit meinem kopf war 😉





  • Hol dir Packteyzer (kostenlos) und schau dir an weleche daten du wirklich sendest



  • Ein weiteres Problem, das du hast, ist, dass du recv die anzahl der Bytes übergeben musst, die es lesen soll. Wenn du zu wenig angibst, wird nicht der ganze Response empfangen, wenn du zu viel angibst, verzögert sich recv.
    Ich hab etwas ähnliches mal im Zuge eines Referates gemacht.
    Meine Lösung war, dass ich den Response Header nach dem Content-Length parse, das ja die Anzahl der Bytes im Body angibt.
    Hier ein Auszug:

    // receive response
    ULONG nBytesTraffic = Cache.nRequestLength;
    int nBytesReceived = 0;
    BOOL bResponseIsHeader = TRUE;
    char cTmpBuffer = 0;
    // receive header
    UINT nContentLength=0;
    char strLastHeaderLine[150];
    char cLastChar = 0;
    memset(strLastHeaderLine, 0, 150);
    
    while (true)
    {
        recv(mySocket, &cTmpBuffer, 1, 0);
        nBytesTraffic ++;
        if (cTmpBuffer != '\n')
        {
            strLastHeaderLine[strlen(strLastHeaderLine)] = cTmpBuffer; // bufferoverrun hier möglich
        }
        else
        {
            UINT nPossibleLength = 0;
            if (sscanf(strLastHeaderLine, "Content-Length: %d", &nPossibleLength)>0)
            {
                nContentLength = nPossibleLength;
            }
            memset(strLastHeaderLine, 0, 150);
        }
        if (cTmpBuffer == '\r' && cLastChar=='\n') // nach \r\n endet der Header
        {
            break;
        }
        cLastChar = cTmpBuffer;
    }
    
    for (int nBytesLeft=nContentLength; nBytesLeft>0; nBytesLeft--)
    {
        recv(mySocket, &cTmpBuffer, 1, 0);
        nBytesTraffic ++;
    }
    


  • Rapha schrieb:

    Meine Lösung war, dass ich den Response Header nach dem Content-Length parse,

    manchmal wird die Content-Length nicht übermittelt



  • in dem rfc stehen diese 2 möglichkeiten

    GET http://www.w3.org/pub/WWW/TheProject.html HTTP/1.1

    GET /pub/WWW/TheProject.html HTTP/1.1
    Host: www.w3.org

    zumindest find ich nur die 2



  • Vertexwahn schrieb:

    manchmal wird die Content-Length nicht übermittelt

    Das hab ich noch nie gesehen 😉

    Andere Lösungs-Theorie:
    Das Problem ist, dass der HTTP-Webserver die Verbindung nach dem Request nicht beendet. Du könntest versuchen ein HTTP 1.0 Request zu senden (anstatt 1.1), da der Server afaik die Verbindung nach einem Request schließt

    EDIT:
    Wenn du unter Windows arbeitest, würde ich den Request nicht von Hand schreiben, sondern WinInet verwenden.



  • so, habe da jetzt noch ein bissl nach eurer anleitung verändert. das problem war tatsächlich der letzte parameter bei recv. hab den jetzt einfach ma genauso groß gemacht wie die variable für die antwort. die sache is jetzt die. der empfängt jetzt was (dank euch) und hält sich halt nich ewig mit dem warten auf. jedoch gibt er nix aus. die entsprechenden zeilen sind die:

    //	Request zusammenstellen und abschicken
    string strRequestMessage = "GET " + this->m_strFolder + " HTTP/1.1 \r\n Host: " + this->m_strServer + " \r\n \r\n";
    
    //	Request erfolgreich ausgeführt
    if( send( (SOCKET) this->m_Socket, strRequestMessage.c_str(), strlen( strRequestMessage.c_str() ), 0 ) )
    {
    	//	Statusmeldung ausgeben
    	cout << endl << "  HTTP Request:" << endl << "  >> Uebertragung erfolgreich" << endl << endl << "  ";
    
    	//	-------------------------------
    	//	Response auswerten und ausgeben
    	//	-------------------------------
    	int nReciveStatus = recv( ( SOCKET ) this->m_Socket, this->m_szRespose, 1000, 1000 );				
    
    	if( nReciveStatus > 0 )
    	{
    		cout << endl << "  HTTP Response:" << endl << "  >> " << this->m_szRespose;
    		this->m_szRespose[ nReciveStatus ] = 0;
    		cout << endl << "  >> " << this->m_szRespose;
    	}
    }
    


  • Rapha schrieb:

    Ein weiteres Problem, das du hast, ist, dass du recv die anzahl der Bytes übergeben musst, die es lesen soll. Wenn du zu wenig angibst, wird nicht der ganze Response empfangen, wenn du zu viel angibst, verzögert sich recv.

    Genau das hab ich ja bereits angesprochen (siehe mein vorheriger Post) 😉



  • wenn ich mir die nReciveStatus ansehen ist diese auf -1 nach dem recv(). das heißt doch, dass das ganze ien fehrlschlag ist, oder? dann wäre es nämlich kein wunder dass der nix ausgibt. bei -1 geht der ja auch nicht ins if rein, was danach kommt.



  • Übergib recv mal nicht 1000 sondern z.B. 5



  • da ändert sich dann auch nichts, wenn ich 5 oder 9 oer 17 oder so mache. aber mit dem request hat der fehler jetzt nichts zu tun, oder? nich das der request falsch ist.



  • gib dir doch mal den Request mit cout aus und teste ihn mit telnet (poste ihn am besten noch hier rein).



  • der request sieht eigentlich richtig aus. nur dass halt \r\n vom compiler interprestiert werden. muss ich die zeichen escapen?



  • der request sieht so aus:

    GET /content/news/index.php HTTP 1.0
    Host: www.futures-net.de

    die \r\n werden ja bei der ausgabe vom compiler interpretiert. is das vl der fehler?



  • wie sieht dein quellcode im moment aus?



  • im moment sieht der so aus:

    /*	INFORMATIONEN ZUM PROGRAMM:
      *	* * * * * * * * * * * * * * * * * * * * * * *
      *
      *	Sinn und Zweck:
      *	==============
      *	Socketverbindung zu entferntem Server um Datei anzusprechen
      *
      *	Hilfe, Tutorials, MSDN, etc.:
      *	=========================
      *	RFC zu HTTP		>>>>>		http://www.faqs.org/rfcs/rfc2616.html
      *	CodingCommunity		>>>>>		http://www.codingcommunity.de/wbb2/thread.php?postid=17671#post17671
      *	c-plusplus.net Forum	>>>>>		http://www.c-plusplus.net/forum/viewtopic-var-p-is-890601.html#890601
      *	C++ Forum			>>>>>		http://www.fun-soft.de/showtopic.php?threadid=12887&post_start=lastpage&time=1129121979
      *	Socket Tutorial		>>>>>		http://beej.us/guide/bgnet/output/htmlsingle/bgnet.html#sendrecv
      *
      *	Einbinden in Günthers Programm:
      *	============================
      *	Ausgaben entfernen & Zielserver, Verzeichnisstruktur, etc. im Konstruktor statisch festlegen
      */
    
    #include <iostream>
    #include <string>
    #include <stdlib.h>
    using namespace std;
    #include <winsock.h>
    
    //
    //	CHttpRequest
    //
    class CHttpRequest
    {
    	private:
    		string m_strServer;			//	Name des Zielservers (z.b. www.microsoft.com)
    		string m_strFolder;			//	Serververzeichnis der Zieldatei
    		string m_strUrl;			//	Komplette Ziel-URL (z.b. www.microsoft.com/windows/default.aspx)
    		char m_szIp[20];			//	IP Adresse des Zielservers, ermittelt nach dem Name
    		char m_szRespose[ 1000 ];	//	variable für die HTTP-Response
    
    		SOCKET m_Socket;			//	Für Socketverbindung
    		WSADATA m_wsaData;			//	Für Socketverbindung
    		sockaddr_in m_Address;		//	Für Socketverbindung
    
    	public:
    
    		//
    		//	Konstruktor
    		//
    		CHttpRequest( void )
    		{
    			//	Initialisieren mit leeren Werten
    			this->m_strServer = "";
    			this->m_strFolder = "";
    			this->m_strUrl = "";
    			strcpy( this->m_szIp, "" );
    			strcpy( this->m_szRespose, "" );
    		}
    
    		//
    		//	Destruktor
    		//
    		~CHttpRequest( void )
    		{
    			WSACleanup();
    		}
    
    		//
    		//	URL einlesen und IP ermitteln
    		//
    		void SetServerInformation( void )
    		{
    			if( 0 != WSAStartup( MAKEWORD(1,2), &this->m_wsaData) )
    				cout << "WSA konnte nicht initialisiert werden.";
    
    			//	URL einlesesn
    			cout << endl << "  Server eingeben (z.b. www.microsoft.com):" << endl << "  >> ";
    			cin >> this->m_strServer;
    
    			//	Verzeichnis einlesen
    			cout << endl << "  Verzeichnis eingeben (z.b. /windows/default.aspx):" << endl << "  >> ";
    			cin >> this->m_strFolder;
    
    			// 	URL zusammensetzen
    			this->m_strUrl = this->m_strServer + this->m_strFolder;
    
    			//	IP ermitteln
    			hostent *dns = gethostbyname( this->m_strServer.c_str() );
    			sprintf( this->m_szIp, "%u.%u.%u.%u",
    				( unsigned char ) dns->h_addr_list[0][0], ( unsigned char ) dns->h_addr_list[0][1],
    				( unsigned char ) dns->h_addr_list[0][2], ( unsigned char ) dns->h_addr_list[0][3] );
    
    			//	Ausgabe
    			cout << endl << "  IP Adresse des Servers:" << endl << "  >> " << this->m_szIp << endl;
    			cout << endl << "  Zielverzeichnis:" << endl << "  >> " << this->m_strUrl << endl;
    		}
    
    		//
    		//	Verbindung aufbauen
    		//
    		void Connect( void )
    		{
    			//	Socket erstellen
    			m_Address.sin_family = AF_INET;
    			m_Address.sin_port = htons( 80 );	// 80 = Port
    			m_Address.sin_addr.s_addr = inet_addr( this->m_szIp);
    
    			//	Socket initialisieren
    			this->m_Socket = socket( AF_INET, SOCK_STREAM, 0);
    			if( 0 == this->m_Socket )
    				cout << endl << "  Statusmeldung" << endl << "  >> Fehler - Socket konnte nicht initialisiert werden.";
    
    			//	Verbindung aufbauen
    			if( -1 == connect( ( SOCKET ) this->m_Socket, ( sockaddr * ) &this->m_Address, sizeof( this->m_Address ) ) )
    				cout << endl << "  Statusmeldung" << endl << "  >> Fehler - Verbindung konnte nicht hergestellt werden.";
    
    			//	Port zuweisen	Nötig ???
    			//bind( ( SOCKET ) this->m_Socket, ( sockaddr * ) &this->m_Address, 0 );
    		}
    
    		//
    		//	HTTP Request ausführen
    		//
    		void DoHttpRequest( void )
    		{
    			//	Request zusammenstellen und abschicken
    			//string strRequestMessage = "GET " + this->m_strUrl + " HTTP/1.1";
    			//string strRequestMessage = "GET " + this->m_strFolder + " \r\n\r\n HTTP/1.0 \r\n Host: " + this->m_strServer + " \r\n \r\n";
    			string strRequestMessage =	"GET " + this->m_strFolder +" HTTP/1.1\r\n" + "Referer: " + this->m_strServer + "\r\n" +
    										"User-Agent: IG Application\r\nAccept-Charset: windows-1252, utf-8, utf-16, iso-8859-1;q=0.6, *;q=0.1\r\n" +
    										"Host: " + this->m_strServer + "\r\n" + "Accept-Encoding: chunked\r\n\r\n";
    			cout << endl << strRequestMessage;
    
    			//	Request erfolgreich ausgeführt
    			if( send( (SOCKET) this->m_Socket, strRequestMessage.c_str(), strlen( strRequestMessage.c_str() ), 0 ) )
    			{
    				//	Statusmeldung ausgeben
    				cout << endl << "  HTTP Request:" << endl << "  >> Uebertragung erfolgreich" << endl << endl << "  ";
    
    				//	Response auswerten und ausgeben
    				int nReciveStatus = recv( ( SOCKET ) this->m_Socket, this->m_szRespose, 1000, 5 );				
    
    				if( nReciveStatus > 0 )
    				{
    					cout << endl << "  HTTP Response:" << endl << "  >> " << this->m_szRespose;
    					this->m_szRespose[ nReciveStatus ] = 0;
    					cout << endl << "  >> " << this->m_szRespose;
    				}
    ///////////////////// DEBUG /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    				else
    					cout << "DEBUG: nReciveStatus = " << nReciveStatus << endl << "  " << WSAGetLastError();
    			}
    			//	Request fehlgeschlagen
    			else
    				cout << endl << "  >> Uebertragung nicht erfolgreich. Request konnte nicht ausgeführt werden." << endl << endl << "  ";
    
    		}
    
    		//
    		//	HTTP Response als string zurückgeben
    		//
    		string GetHttpResponse( void )
    		{
    			return (string) m_szRespose;
    		}
    
    		//
    		//	Verbindung beenden
    		//
    		void Close( void )
    		{
    			WSACleanup();
    		}
    };
    
    //
    //	Main
    //
    int main( void )
    {
    	CHttpRequest Request;
    
    	//	Methoden der Klasse aufrufen
    	Request.SetServerInformation();
    	Request.Connect();
    	Request.DoHttpRequest();
    	Request.Close();
    
    	//	Programmende
    	cout << endl << endl << endl << endl << "  ";
    	system( "pause" );
    	return 0;
    }
    

    die probleme liegen in edr DoHttpRequest()



  • was soll die 5 bei recv?



  • wurde mir in einem post weiter oben empfohlen


Anmelden zum Antworten