Empfangen der Daten nach HTTP-GET



  • Hallo, ich habe ein Prog, dass eine HTML-Seite anfordern und in einen String speichern soll.
    Ich habe allerdings das Problem dass die Seite immer nur teilweise in diesem String steht. Zu einem gewissen Zeitpunkt hört sie einfach auf.
    Das komische ist auch dass sie immer an einer anderen Stelle aufhört.

    #include <stdio.h>
    #include <errno.h>
    #include <string>
    #include <winsock.h>
    #include <io.h>
    #include <iostream.h>
    
    #define HTTP_PORT 80
    
    int main()
    {
    	int sock;
    	struct sockaddr_in host_addr;
    	char *host, *file;
    	char command[1024];
    	char buf[1024];
    
    	unsigned int bytes_sent, bytes_recv;
    
    //Config ---------------------------------------------------------------
    
    	host = "195.27.230.130";
    	file = "/";
    
    //Config-End -----------------------------------------------------------
    
    //Initialisierung
    	WSADATA wsaData;
    
    	if (WSAStartup (MAKEWORD(1, 1), &wsaData) != 0) 
    	{
    	//Error
    	exit (EXIT_FAILURE);
    	}
    
    /* Socket erzeugen */
    	sock = socket (AF_INET, SOCK_STREAM, 0);
    	if (sock == -1) 
    	{
    	//Error
    	exit (EXIT_FAILURE);
    	}
    
    /* Adresse des Servers festlegen */
    
    	// host_addr mit 0en füllen
    	memset( &host_addr, 0, sizeof (host_addr));
    
    	host_addr.sin_family = AF_INET;
    	host_addr.sin_port = htons (HTTP_PORT);
    
    	//host gecastet in host_addr bringen
    	host_addr.sin_addr.s_addr = inet_addr (host);
    
    /* Verbindung aufbauen */
    
    	if (connect(sock, (struct sockaddr *) &host_addr, sizeof(struct sockaddr)) == -1) 
    	{
    	//Error
    	exit (EXIT_FAILURE);
    	}
    
    /* HTTP-GET-Befehl erzeugen */
    	sprintf (command, "GET %s HTTP/1.0\nHost: %s\n\n", file, host);
    /* Befehl senden */
    	bytes_sent = send (sock, command, strlen (command), 0);
    	if (bytes_sent == -1) {
    	//Error
    	exit (EXIT_FAILURE);
    	}
    
    /* Antwort des Servers empfangen und ausgeben */
    
            char rec_data[1000000]      // extra übertrieben groß
    
    	while ((bytes_recv = recv (sock, buf, sizeof(buf), 0)) > 0) 
    	{
    	strcat(rec_data, buf);        //neu empfangenes an String anfügen.
    	}
    
            //rec_data enthält den html code zur späteren verarbeitung
    
    	if (bytes_recv == -1) {
    	//Error
    	exit (EXIT_FAILURE);
    	}
    
    /* Aufräumen */
    
    	closesocket(sock);
    	WSACleanup();
    
    }
    

    Allerdings, jetzt gerade wo ichs hier poste fällt mir auf, dass ma Ende des Strings immer steht: "GET / HTTP/1.0 Host: 195.27.230.130"
    Das müsste ja eigentlich das Ende der Übertragung sein.
    Heisst dass, das der Server mir eben nur diesen Teil schickt?
    Wenn ja, was kann man machen um den gesamten HTML-Code zu bekommen?



  • hi,
    ich hab mal geschaut was sendet mein browser an den webserver:

    GET / HTTP/1.1
    Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-gsarcade-launch, /
    Accept-Language: de-at
    Accept-Encoding: gzip, deflate
    If-Modified-Since: Tue, 19 Jul 2005 20:12:33 GMT
    If-None-Match: "7008c9a-108fe-42dd5eb1"
    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)
    Host: 195.27.230.130
    Connection: Keep-Alive

    und welchen response empfängt der browser:

    HTTP/1.1 200 OK
    Date: Tue, 19 Jul 2005 20:17:46 GMT
    Server: Apache/1.3.31 (Unix) PHP/4.4.0
    Last-Modified: Tue, 19 Jul 2005 20:08:08 GMT
    ETag: "7008c9a-108e2-42dd5da8"
    Accept-Ranges: bytes
    Content-Length: 67810
    Connection: close
    Content-Type: text/html

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
    <title>GIGA.DE</title>
    <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
    <meta name="Title" content="NBC GIGA - Join the Community">
    <meta name="Author" content="NBC GIGA">
    <meta name="Publisher" content="NBC GIGA">
    <meta name="Revisit" content="After 7 days">
    ....
    ....

    du kannst nicht garantieren, dass der Response Body in einem datagramm empfangen wird!
    zitat volkard:
    hängt am von server-os, server-os-einstellungen, webserver-einstellungen, client-os, client-os-einstellungen, client-browser-einstellungen[?]
    send() nimmt jede größe. das bs hackt das paket in kleine datagramme und schickt die weg.
    das empfänger-bs setzt die wieder zusammen. und liefert dir, in größen, die es mag. 😃

    um den ges. Response Body zu bekommen musst du halt so oft recv aufrufen bis alles da ist...

    cu



  • wie du siehst ist hier Content-Length: 67810 gross,
    und der winsock buffer bei windows liegt bei 50kB, ich bin mir aber nicht sicher...gefunden hab ich mit google auch nichts...vielleicht kann jemand anders paar genauere details sagen...

    cu



  • Ich denke eher dein Problem liegt bei strcat. Du terminierst den Buffer nach dem Aufruf von recv ja gar nicht mit 0.



  • @cplusplus.: er ruft doch recv schon in einer Schleife auf. 😕 😕



  • ja, nicht mal gesehn;-)

    mach mal:

    #include <string>
    using namespace std;
    
    string rec_data;
    while ((bytes_recv = recv (sock, buf, sizeof(buf), 0)) > 0) 
    {
        rec_data += buf;
    }
    

    cu



  • bevor man dies tut sollte man erstmal buf 0 terminieren.



  • So, ich hab mir mal mit Ethereal angeschaut, was mein Browser da sendet.
    Er sendet noch mit :
    Keep-Alive: 300
    Connection: keep-alive

    Wenn ich das mitsende bekomme ich die ganze html-Seite rein.

    Dann hatte ich dadurch, dass buf nicht 0 terminiert war immer meine Anfrage hinter jedem Block. Hab jetzt Terminiert.
    Nun habe ich aber noch das Problem, das an den Stellen wo früher meine Anfrage drinwar, also immer am ende eines buf's, eine Zeile von weiter oben, also z.b.

    <td align='center' width='85'><img border='0' src='http://bild1.gif' width='42' height='22'></td>
                <td align='center' width='85'><img border='0' src='http://bild2.gif' width='42' height='22'></td>
                <td align='center' width='85'><img border='0' src='http://bild3.gif' width='42' height='22'></td>
                <td align='center' width='85'><img border='0' src='http://bild4.gif' width='42' height='22'></td>
                <td align='center'></td>
              </tr>
              <tr>
                <td align='center'><i><b>&nbsp;&nbsp;</b></i></td>
                <td align='center' width='85'><i><b><font color='#ffffff'>TXT1</font></b></i></td>
                <td align='center' width='85'><i><b><font color='#ffffff'>TXT2</font></b></i></t[e]prod[/e]th='85'><img border='0' src='http://bild3.gif' width='42' he[e]prod[/e]d>
                <td align='center' width='85'><i><b><font color='#ffffff'>TXT3</font></b></i></td>
                <td align='center' width='85'><i><b><font color='#ffffff'>TXT4</font></b></i></td>
                <td align='center'><i><b>&nbsp;&nbsp;</b></i></td>
    

    Der Teil zwischen den ∏, steht in der Tatsälichen HTML-File nicht dort. Er kommt also von oben. Nun frage ich mich nur wiso.

    In der original sieht es so aus:

    [code]
                <td align='center' width='85'><img border='0' src='http://bild1.gif' width='42' height='22'></td>
                <td align='center' width='85'><img border='0' src='http://bild2.gif' width='42' height='22'></td>
                <td align='center' width='85'><img border='0' src='http://bild3.gif' width='42' height='22'></td>
                <td align='center' width='85'><img border='0' src='http://bild4.gif' width='42' height='22'></td>
                <td align='center'></td>
              </tr>
              <tr>
                <td align='center'><i><b>&nbsp;&nbsp;</b></i></td>
                <td align='center' width='85'><i><b><font color='#ffffff'>TXT1</font></b></i></td>
                <td align='center' width='85'><i><b><font color='#ffffff'>TXT2</font></b></i></td>
                <td align='center' width='85'><i><b><font color='#ffffff'>TXT3</font></b></i></td>
                <td align='center' width='85'><i><b><font color='#ffffff'>TXT4</font></b></i></td>
                <td align='center'><i><b>&nbsp;&nbsp;</b></i></td>
    

    [/code]

    Falls es an der Terminierung liegt, die habe ich wie folgt gemacht:

    while ((bytes_recv = recv (sock, buf, sizeof(buf)-1, 0)) > 0) 
    	{
    	buf[sizeof(buf)-1]='\0';
    	strcat(htout,buf);
    	}
    

    Den Fehler kann ich irgendwie nicht verstehen



  • statt sizeof(buf) nimmst du bytes_recv



  • ich meine "solltest du nehmen"



  • bei mir habe ich das so gemacht

    und das funktioniert auch ohne das irgendwas da ist wo es nicht hingehört

    char tempbuffer = 2048;

    cout << "request sent.\n";
    
    		cout <<	"Dumping received data...\n\n";
    		// Loop to print all data
    		while(true)
    		{
    			int retval;
    			retval = recv(hSocket, tempBuffer, sizeof(tempBuffer)-1, 0);
    			if (retval==0)
    			{ 
    				break; // Connection has been closed
    			}
    			else if (retval==SOCKET_ERROR)
    			{
    				throw HRException("socket error while receiving.");
    			}
    			else
    			{
    				// retval is number of bytes read
    				// Terminate buffer with zero and print as string
    				tempBuffer[retval] = 0;
    				cout << tempBuffer;
                }
    

Anmelden zum Antworten