Probleme de buffer avec la fonction recv()

shocknurris Messages postés 4 Date d'inscription mercredi 11 mai 2005 Statut Membre Dernière intervention 11 mai 2005 - 11 mai 2005 à 10:48
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 - 11 mai 2005 à 19:47
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

cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
11 mai 2005 à 12:46
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.
0
shocknurris Messages postés 4 Date d'inscription mercredi 11 mai 2005 Statut Membre Dernière intervention 11 mai 2005
11 mai 2005 à 14:52
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
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
11 mai 2005 à 15:54
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 ?
0
shocknurris Messages postés 4 Date d'inscription mercredi 11 mai 2005 Statut Membre Dernière intervention 11 mai 2005
11 mai 2005 à 16:22
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
0

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

Posez votre question
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
11 mai 2005 à 16:32
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;


}
0
vincentsage Messages postés 17 Date d'inscription mercredi 26 mai 2004 Statut Membre Dernière intervention 3 novembre 2005
11 mai 2005 à 17:22
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;

}
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
11 mai 2005 à 17:32
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.
0
shocknurris Messages postés 4 Date d'inscription mercredi 11 mai 2005 Statut Membre Dernière intervention 11 mai 2005
11 mai 2005 à 19:40
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
0
cs_aardman Messages postés 1905 Date d'inscription mercredi 22 janvier 2003 Statut Membre Dernière intervention 17 septembre 2012 3
11 mai 2005 à 19:47
Salut,
Si tu es sous windows, tu peux appeler WSAGetLastError() pour avoir le numero de l'erreur.
0
Rejoignez-nous