Probleme wsock protocole HTTP

Résolu
Target67 Messages postés 5 Date d'inscription lundi 28 février 2005 Statut Membre Dernière intervention 6 juillet 2008 - 28 juin 2008 à 23:11
Target67 Messages postés 5 Date d'inscription lundi 28 février 2005 Statut Membre Dernière intervention 6 juillet 2008 - 30 juin 2008 à 21:22
Alors je veux faire une petite appli qui permet de télécharger des fichiers sur le net suivant le protocole HTTP dont voici le code de la partie qui va chercher le fichier:

void getfile(SOCKET sock,SOCKADDR_IN sin,char* file){

FILE * infile;
infile = fopen(file,"wb");
char* mes = new char[255];
char* buffer = new char[1024];
int byteget;
bool header = false;
char* buf2;

connect(sock,(SOCKADDR *)&sin,sizeof(sin));

sprintf(mes,"GET /home/patcher/%s HTTP/1.0\r\nConnection: close\r\n\r\n",file);

send(sock,mes,strlen(mes),0);

while((byteget = recv(sock,buffer,1024,0)) > 0 ){
              
               if( !header ){
               buf2 = strstr(buffer,"\r\n\r\n") + 4;
               fwrite(buf2,byteget - (buf2-buffer),1,infile);
               header = true;
               }else{
                     fwrite(buffer,byteget,1,infile);
               }
}

shutdown(sock,2);
fclose(infile);

}

Je l'utilise dans une boucle dans laquelle je rentre un nom de fichier a télécharger, ça marche parfaitement la première fois (fichier complet sans soucis) mais si je lance un 2e téléchargement ensuite, celui-ci me donne un fichier vide... Merci de bien vouloir m'aider ^^

6 réponses

cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
29 juin 2008 à 22:45
Salut,

j'ai bien compris a quoi servait le strstr(), mais comme son nom
l'indique c'est une fonction qui s'applique sur des chaines de
caracteres uniquement, pas sur des données brutes que tu recois avec
recv().

Pour le socket, il faut en recreer un nouveau pour chaque connexion (socket(), closesocket()).
3
cs_jfrancois Messages postés 482 Date d'inscription vendredi 26 août 2005 Statut Membre Dernière intervention 5 décembre 2009 2
29 juin 2008 à 10:22
Bonjour,

Peut-être parce qu'il manque les delete qui doivent aller avec les new ?

Jean-François
0
Target67 Messages postés 5 Date d'inscription lundi 28 février 2005 Statut Membre Dernière intervention 6 juillet 2008
29 juin 2008 à 12:02
Merci de ta réponse.

Non j'ai essayé a tout hasard, mais j'avais déjà commencé d'autres versions où  l'allocation de mémoire était faite avant itération (donc aucune necessité de delete entre chaque itération).

Je tiens aussi a préciser qu'en faisant des tests similaires avec le protocole FTP (en exécutant les instructions correctement) j'arrivais aussi a downloader un premier fichier mais pas un deuxième...

Ma question serait de savoir si une fois le socket fermé, il faut le réinitialiser d'une manière quelconques ou quoi? ...
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
29 juin 2008 à 17:14
Salut,
Commence surtout par traiter les erreurs des fonctions
winsock et d'afficher des messages en conséquence: ta fonction
n'affiche rien, ne log rien, ne retourne rien: a moins d'etre devin
c'est impossible a debuger. A mon avis, c'est le deuxieme connect() qui
échoue, je pense pas qu'on puisse réutiliser un socket de cette maniere
(même apres un shutdown).

Ensuite, y'a d'autres problemes, comme la fuite de mémoire signalée par
jfrancois, mais plus grave a mon avis, c'est le
"strstr(buffer,"\r\n\r\n")": le serveur n'envoie pas de chaine terminée
par 0, donc on peut pas utiliser strstr. Autre problême mineur, que se
passe-t-il lorsqu'on ne recoit qu'une partie de la réponse lors du
premier recv() ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Target67 Messages postés 5 Date d'inscription lundi 28 février 2005 Statut Membre Dernière intervention 6 juillet 2008
29 juin 2008 à 19:18
Merci pour ta réponse, il faudrait en effet que je soit un peu plus rigoureux lorsque je code et des récups d'erreurs ne font jamais de mal...

En ce qui concerne la fuite de mémoire, je l'ai réglé suite au message de jfrancois, en ce qui concerne le strstr il marche très bien (je comprend pas ce que tu veux dire par la), je l'utilise pour virer le header de la réponse du serveur HTTP au niveau des recv il gère tres bien les réponse au dela de la taille du buffer (j'ai envoyé au travers un fichier de 1Mo dont j'ai verifié le checksum), la boucle sert à ça...

Sinon lorsque je mes un récup d'erreur à la deuxieme tentative il me sort un code d'erreur 10056 >> Socket is already connected.

Que faudrait-il que je fasse? passer par des pointeurs et effacer les socket a la fermeture?
0
Target67 Messages postés 5 Date d'inscription lundi 28 février 2005 Statut Membre Dernière intervention 6 juillet 2008
30 juin 2008 à 21:22
Merci beaucoup, ça marche maintenant...

Pour ce qui est  de la question du strstr, il est necessaire que ce soit une chaine uniquement car c'est le caractère \0 qui arrête la recherche non? dans mon cas j'ai choisi plutôt que de bidouiller avec des memcmp et memchr de rajouter un caractère \0 a la fin de la chaine et de faire coller le recv de façon à ce qu'il n'écrive pas par dessus ce dernier caractère, ce qui donne avec toutes les modifs:

void getfile(SOCKADDR_IN sin,char* file){
char* mes = new char[255];
char* buffer = new char[1025];
buffer[1024] = '\0';
int byteget;
bool header = false;
char* buf2;

SOCKET sock;

sock = socket(AF_INET,SOCK_STREAM,0);

if(connect(sock,(SOCKADDR *)&sin,sizeof(sin))==SOCKET_ERROR){
         Affsockerror();
}else{         
FILE * infile;
infile = fopen(file,"wb");

sprintf(mes,"GET /home/patcher/%s HTTP/1.0\r\nConnection: close\r\n\r\n",file);

send(sock,mes,strlen(mes),0);

while((byteget = recv(sock,buffer,1024,0)) > 0 ){
               
               if( !header ){
               buf2 = strstr(buffer,"\r\n\r\n") + 4;
               fwrite(buf2,byteget - (buf2-buffer),1,infile);
               header = true;
               }else{
                     fwrite(buffer,byteget,1,infile);
               }
}
closesocket(sock);
fclose(infile);
}
delete(mes);
delete(buffer);
}

Merci encore pour votre aide a tous les deux ^^
0
Rejoignez-nous