empfange mit recv nach http request nicht vollständig.



  • Hi,

    ich hab mir quasi einen mini browser geschrieben.
    er sendet nach eingabe der url einen http request und erpfängt die antwort des servers.
    leider empfängt er irgendwie nicht das vollständige dokument, sondern nur einen teil. zwischen 1300-1450 zeichen (je nach seite).

    #define MESSAGE_SIZE 5000
    
    [...]
    
    char buffer[MESSAGE_SIZE]="";
    
    [..]
    
     rc = recv(sd,buffer,MESSAGE_SIZE - 1,0);
      if(rc<0){
        perror("error: cannot receive");
        return 1;
      }
    

    Wenn ich danach rc ausgabe, dann sind wie oben angegeben immer nur ein teil der zeichenmenge, die er eigentlich empfangen müsste.

    Hat jemand eine Idee? ich bin der Meinung, es lief auch mal korrekt.



  • recv in einer Schleife aufrufen.



  • Ich habs schon probiert mit: MESSAGE_SIZE 1023;

    und dann mit ner while schleife um das recv, aber dann bekomm ich beim ersten mal eben die 1023 zeichen und beim zweiten aufruf meine 358, wobei ich wieder in meinem mittel wäre.

    und wenn ich MESSAGE_SIZE 5000 habe und er nicht mal die 5000 voll macht, da bringt doch auch keine schleife was, oder sehe ich das falsch?



  • es ist nicht garantiert, dass recv() den buffer voll macht.

    benutz recv() in ner schleife, um den buffer voll zu machen. wenn keine daten mehr vorhanden sind (die verbindung geschlossen ist), dann gibt recv() 0 (null) zurueck.

    such mal nach "beej's networking guide".





  • Erstmal danke für die vielen Ratschläge.
    Ich habs nun doch wieder mit ner While gemacht und den buffer mit strncat hintereinanders gehängt.

    Funktioniert eigentlich auch alles, bis auf eines.
    Bei manchen Seiten empfange ich viele Zeichen, aber ich hab das gefühl der gibt nicht alle aus.

    Beispielsweise heise.de ~31000 Zeichen, aber am Ender der Ausgabe steht nicht </html>, sondern sie endet in der Mitte.

    Bei t-online.de (~62000 Zeichen) endet es mit einem </html>

    www.mymtw.com (~180000 Zeichen) selbiges wie bei heise.de

    Woran kann das liegen?

    Ich habe mir mal den Funktionswert von recv dazu ausgeben lassen und der sieht bei heise.de z.B. so aus:

    1400
    1400
    ...
    1400
    874
    0

    Da sollte doch alle geklappt haben oder nicht? Aber wieso geht t-online mit mehr zeichen problemlos?
    Mein Buffer hat die größe 640000 und das nullzeichen setze ich, indem ich alle funktionswerte addiere und dann nachher buffer[addiertefunktionswerte] = '\0';
    sage.

    vielleicht habt ihr da noch n kleinen tipp 🙂



  • Das habe ich mal gebaut für HTTP:

    #define HTTP_GET	"GET %s HTTP/1.1\n"
    #define HTTP_HOST	"HOST: %s\n"
    
    int
    download_file(char *url)
    {
    	char host[MAXLEN] = {0}, path[MAXLEN] = {0}, file[MAXLEN] = {0};
    	char buffer[MAXLEN], timestr[30], filename[MAXLEN], c;
    	int	res, recv_data = 0, http_socket;
    	unsigned long file_size = -1;
    	struct hostent *he = NULL;
    	struct sockaddr_in sa;
    	unsigned int pos;
    	FILE *targetfile;
    
    	if(strstr(url, "http://") == url)
    		url += 7;
    
    	/* Parse host/ip, path of the file and filename */
    	strncpy(host, url, strchr(url, '/') - url);
    	strncpy(path, strchr(url, '/'), strlen(url) - (strchr(url, '/') - url));
    	strncpy(file, strrchr(url, '/') + 1, strlen(url) - (strrchr(url, '/') - url));	
    
    	/* Connect to the server */
    	if(!(http_socket = socket(AF_INET, SOCK_STREAM, 0)))
    	{
    		log_append(log_main, LOG_ERROR, "download_file().socket() returned errno %d (%s).", errno, strerror(errno));
    		return 1;
    	}
    
    	memset(&sa, 0, sizeof(struct sockaddr));
    
    	sa.sin_family = AF_INET;
    	sa.sin_port = htons(80);
    
    	if(!(he = gethostbyname(host)))
    	{
    		if((sa.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
    		{
    			log_append(log_main, LOG_ERROR, "Unable to resolve hostname - download_file().");
    			return 2;
    		}
    	}
    	else
    	{
    		bcopy(he->h_addr,(struct in_addr *) &sa.sin_addr, he->h_length);
    	}
    
    	if(connect(http_socket,(struct sockaddr *) &sa, sizeof(sa)) < 0)
    	{
    		log_append(log_main, LOG_ERROR, "Unable to connect: errno %d (%s) - download_file().", errno, strerror(errno));
    		return 3;
    	}
    
    	/* Send the required http lines */
    	snprintf(buffer, sizeof(buffer), HTTP_GET, path);
    	send(http_socket, buffer, strlen(buffer), 0);
    	snprintf(buffer, sizeof(buffer), HTTP_HOST, host);
    	send(http_socket, buffer, strlen(buffer), 0);
    	snprintf(buffer, sizeof(buffer), "\r\n");
    	send(http_socket, buffer, strlen(buffer), 0);
    
    	/* Receive -> open the file and wait for the reply */
    	time_t local = time(NULL);
    	strftime(timestr, sizeof(timestr), "%m-%d-%Y--%H-%M-%S", localtime(&local));
    	snprintf(filename, sizeof(filename), "%s--%s", timestr, file);
    	targetfile = fopen(filename, "w");
    
    	while(1)
    	{
    		memset(buffer, 0, sizeof(buffer));
    		pos = 0;
    
    		while(1)
    		{
    			if((res = recv(http_socket, &c, 1, 0)) <= 0)
    			{
    				log_append(log_main, LOG_ERROR, "download_file().recv() <= 0 - lost connection.");
    				fclose(targetfile);
    				remove(filename);
    				close(http_socket);
    				return 4;
    			}
    
    			if(!recv_data)
    			{
    				if(c == '\n' || c == '\0')
    					break;
    
    				if(c == '\r')
    					continue;			
    
    				buffer[pos++] = c;
    			}
    			else
    			{
    				fprintf(targetfile, "%c", c);
    
    				/* Decrease file_size and exit both loops when it's 0 */
    				if(!--file_size)
    					break;
    			}
    		}
    
    		if(!recv_data)
    		{
    			char *argv[256];
    			int argc;
    
    			buffer[pos] = '\0';
    			argc = split_string(buffer, argv);
    
    			/* Check if the url is ok */
    			if(!strcmp(argv[0], "HTTP/1.1") && strcmp(argv[1], "200"))
    			{
    				log_append(log_main, LOG_ERROR, "Download failed. Server returned status %s.", argv[1]);
    				fclose(targetfile);
    				remove(filename);
    				close(http_socket);
    				return 5;
    			}
    
    			/* Save the file size */
    			if(!strcmp(argv[0], "Content-Length:"))
    				file_size = strtoul(argv[1], NULL, 0);
    
    			/* All following lines are data we need to save to the file */
    			if(!strcmp(argv[0], ""))
    				recv_data = 1;
    		}
    
    		if(!file_size)
    			break;
    	}
    
    	fclose(targetfile);
    	close(http_socket);
    
    	return 0;
    }
    

    Ka, ob dir das was hilft.



  • http://www.lugbz.org/documents/smart-questions_de.html

    minimalbeispiel, das dein problem darstellt bitte. sonst hat keiner was davon, dir zu helfen.


Anmelden zum Antworten