2009-10-19 7 views
4

J'ai un client HTTP de base mis en place en C++, ce qui fonctionne bien jusqu'à présent. C'est pour une tâche d'école, donc il y a beaucoup plus à faire, mais j'ai un problème. J'utilise la fonction recv() dans une boucle while pour ajouter à plusieurs reprises des parties de la réponse à mon tampon de réponse, puis générer ce tampon à chaque fois. Le problème est que, à la fin de chaque partie de la réponse, la requête HTTP est également activée. Par exemple, la réponse sera un morceau du code source de la page, suivi de "GET/HTTP/1.1 ...", suivi par le morceau suivant, puis de nouveau "GET ...", et bientôt.Réponse HTTP inhabituelle dans la programmation de base C++

Voici mon code correspondant:

// Prepare request 
char request[] = "HEAD /index.html HTTP/1.1\r\nHOST: www.google.com\r\nCONNECTION: close\r\n\r\n"; 

// Send request 
len = send(sockfd, request, sizeof(request), 0); 

// Write/output response 
while (recv(sockfd, buf, sizeof(buf), 0) != 0) 
{ 
    // Read & output response 
    printf("%s", buf); 
} 

Répondre

7

Le tampon est non nulle fin, ce qui est nécessaire pour les chaînes en C++. Lorsque vous voyez le "extra GET", vous voyez de la mémoire que vous ne devriez pas être parce que le stdlib a essayé d'imprimer votre tampon, mais n'a jamais trouvé un caractère '\0'.

Une solution rapide est de forcer le tampon à terminer:

int n = 1; 
while (n > 0) { 
    n = recv(sockfd, buf, sizeof(buf), 0); 
    if (n > 0) { 
     // null terminate the buffer so that we can print it 
     buf[n] = '\0'; 

     // output response 
     printf("%s", buf); 
    } 
} 
+0

Fait sens. Merci! –

0

recv ne pas ajouter une terminaison de chaîne \0 dans la mémoire tampon recieved - il fonctionne en binaire brut. Donc, votre printf est en train d'être envoyé de votre buffer buf (et finit apparemment par regarder votre buffer request).

Soit ajouter un terminateur NUL à la fin de buf, ou imprimer le tampon d'un caractère à la fois en utilisant putchar() (ces deux approches contraindra pour stocker la valeur retournée par recv()).

0

L'appel recv ne mettra pas fin à buf; Au lieu de cela, il vous fournira simplement les données brutes reçues du fil. Vous devez enregistrer la valeur de retour de recv, puis ajouter vous-même un octet de terminaison null dans buf avant de l'imprimer. Par conséquent, vous ne pouvez demander que sizeof (buf) -1 octets.

1

Je suppose que c'est parce que votre buf est alloué en mémoire juste en dessous de votre request. Lorsque vous appelez printf sur le tampon, printf va imprimer autant que possible avant de trouver un caractère NUL (qui marque la fin de la chaîne). S'il n'y en a pas, cela ira jusqu'à la demande. Et généralement, il n'y en aura pas, parce que recv est pour recevoir des données binaires et ne sait pas que vous voulez traiter sa sortie une chaîne.

Une solution rapide serait de limiter l'opération de réception à sizeof(buf)-1, et d'ajouter explicitement la même terminaison NUL, en utilisant la taille des données renvoyées:

while ((nr = recv(sockfd, buf, sizeof(buf), 0)) > 0) 
{ 
    buf[nr] = 0; 
    ... 
} 

Bien sûr, pour que cela (légèrement) En toute sécurité, vous devez vous assurer que vous recevrez toujours des données imprimables.

+0

Merci pour votre explication. –

Questions connexes