Probleme de buffer avec la fonction recv()

Signaler
Messages postés
4
Date d'inscription
mercredi 11 mai 2005
Statut
Membre
Dernière intervention
11 mai 2005
-
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
-
Bonjour a tous,

effectivement je suis au bord du suicide, nan quand meme pas, mais j'en
dors plus tellement je ne trouve pas de solution et ne comprend pas.



Bon déja, droit au but mon bout de code :



---------------------------------

char *buffer;

buffer=(char *)malloc(sizeof(char)*16581375);




erreur=send(sock,requete,strlen(requete),0);




if(erreur!=SOCKET_ERROR)

{memset(buffer,0,16581375);


ret=recv(sock,buffer,16581375,0);

if(ret>0)

{


buffer[ret] = '\0';

printf("%s",buffer);

}}

---------------------------------



La variable "requete" contient une requete http de type GET,

les données s'envoient et je les recoits et mon petit code comme vous le voyez affiche la réponse du serveur.

Le problème c'est lorsque je demande le "téléchargement" d'une page de
15000 octets par exemple il refuse de stocker plus de 8000 octets et ca
me bloque complétement dans mon programme, car j'ai besoin de "recevoir
toute la page".



La variable ret qui m'indique le nombre de caractères recus a bien
comme valeur 15000 (donc 15000 octets recus) mais le buffer n'en
contient que 8000 (alors qu'il peut contenir 16581375 octets).



J'ai exploré quelques pistes, et ca ne vient pas d'un probleme a
l'affichage. Peut etre d'un probleme d'allocation de mémoire, je sais
pas trop.



Pour infos si ca peut aider, je compile avec BCC (borland compiler (freecommandlinestools) et je suis sous windows xp sp2.



Si quelqu'un trouve rien qu'une piste, ca serait un énorme soulagement,
car j'ai beau regarder d'autres codes du meme genre et personne semble
avoir ce problème.



Merci d'avance

9 réponses

Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,
C'est pas vraiment un probleme, ca vient du protocol tcp.
C'est a toi (ton prog) de reappeler recv() tant que tu n'a pas recus autant d'octets que tu souhaites.
Messages postés
4
Date d'inscription
mercredi 11 mai 2005
Statut
Membre
Dernière intervention
11 mai 2005

merci de ta réponse,


mais tu es sur de ce que tu dis ?


car comme je l'ai dit dans mon premier message, lorsque j'utilise mon code, la fonction recv recoit bien le nombre de caractère que je veux (car elle retourne le bon nombre de caractères de la page que je veux), mais après le buffer n'est pas correctement remplit, c pour ca, j'aurais plutot pensé qu'il y avait un problème au niveau de la taille de mon buffer (pas assez grand).

Sinon pour ta piste, je réappelle comment recv ?

while(ret!=??)
{ret=recv(sock,buffer,16581375,0);}

merci en tout cas de ta réponse
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,
Si recv retourne 15000, comment sait tu que le buffer ne contient que 8000 octets en fait ?
Dans ton code, ou est ce que tu affiches ret ?
Messages postés
4
Date d'inscription
mercredi 11 mai 2005
Statut
Membre
Dernière intervention
11 mai 2005

oups je me suis trompé,
et pourtant avant d'avoir modifié mon code (car j'y ait fait des retouches longuement) je n'avais pas la meme valeur dans ret que dans strlen(buffer); c'est pour ca que je pensais que ca venait d'un problème de mémoire.

Et la je viens de vérifier et finalement, recv m'indique bien le nombre de caractère qui est affiché (strlen(buffer), sorry.

peux tu m'indiquer donc comment réappeller recv comme tu la suggèrer dans ton premier message ?

Merci encore aardman
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,
Si tu sais exactement combien d'octet tu dois recevoir, il te suffit de rappeler recv tant que tu n'a pas recu le bon nombre d'octet.
Voila une fonction qui en théorie fait ca (je le n'ai pas testée donc il est probable qu'elle ne fonctionne pas):

int _recv(SOCKET sock,
char *buff,
int len,
int flags)


{



int ret, size;


for(size ret
0; size < len; size += ret)


{


ret = recv(sock, buff + size, len - size, flags);


if(ret SOCKET_ERROR || ret
0)



return ret;


}


return size;


}
Messages postés
17
Date d'inscription
mercredi 26 mai 2004
Statut
Membre
Dernière intervention
3 novembre 2005

Salut, en fait le plus simple c'est de faire une boucle sur le recv,
voila un bout de code d'une fonction qui récupère une page HTML :



char request[REQUEST_SIZE+2],tmp[BUFFSIZE];

char *buffer = new char[MAXPAGESIZE];

int bytesRecv,nb=0,ok=0;



strcpy(request, requ);



do

{

bytesRecv=0;



sock = init_connection(ip_mdr[moteur_de_recherche-1],80);



if(ip_unreachable)

return NULL;



memset(buffer,0,MAXPAGESIZE);

// cout <<endl<<
"ENVOI DE : " << request <<" a
"< 0)

{

bytesRecv += nb;

sprintf(buffer,"%s%s",buffer,tmp);

buffer[bytesRecv] = 0;

}



if(strstr(buffer,"</html>") || strstr(buffer,"</HTML>"))

{


//cout<<"page "<<nbpage<<"
telechargee"<<endl;

printf(".");

ok=1;

break;

}



if ( nb == 0 )

{


cout<<"Connection Fermee par le
serveur"<<endl;

break;

}



if ( nb == SOCKET_ERROR )

{


cout<<"SOCKET_ERROR : Erreur dans la
socket"<<endl;exit(0);

break;

}




//cout<<"fin recv ----->"<<nb<<" octets recu a ce
recv, "<<bytesRecv<<" octets recu en tout"<<endl;

}
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,
L'avantage de mon _recv c'est que - si il marche - il est reutilisable.
Et si on voulait vraiment recuperer la page proprement, il faudrait parser le header de la reponse http, extraire la taille du fichier, et boucler sur cette taille.
Messages postés
4
Date d'inscription
mercredi 11 mai 2005
Statut
Membre
Dernière intervention
11 mai 2005

ok merci pour vos codes, je regarderai tout ca un autre jour,
j'ai rapidement mis la fonction que tu as donné aardman et pour l'instant meme des la premiere execution de la boucle for ret renvoit -1 (socket_error), mais j'ai pas cherché a trouver le problème, ca doit venir du reste de mon prog

thx encore
Messages postés
1905
Date d'inscription
mercredi 22 janvier 2003
Statut
Membre
Dernière intervention
17 septembre 2012
2
Salut,
Si tu es sous windows, tu peux appeler WSAGetLastError() pour avoir le numero de l'erreur.