OVH Cloud OVH Cloud

utilisation de send et recv en sureté

14 réponses
Avatar
Nicolas aunai
salut,


j'utilise dans mon programme en C les fonctions send() et recv(), lors de la
discussion entre un serveur et un client, quelle est la meilleure façon
d'utiliser ses fonctions avec le maximum de sécurité ?

par exemple quand j'utilise recv() je fais :

do{
result=recv(my_sock,(char *)&structure,sizeof(structure),0);
}
while(result<=0);

car recv renvoie le nombre de bytes reçus...

quand j'utilise send je ne fais aucune vérification, est-ce que je devrai
faire un send(bidule...) tant que la fonction retourne SOCKET_ERROR ?


merci d'avance des indics..


--
nico,
http://astrosurf.com/nicoastro
messenger : nicolas_aunai@nospam@hotmail.com

4 réponses

1 2
Avatar
Nicolas aunai
bon ok recv reçoit les données paquet par paquet... mais comment les
place-t-elle dans mon buffer ?

par exemple si j'ai une structure qui contient deux membres : int a; et
euh... disons char temp[20]; comment la fonction met-elle l'entier dans la
variable 'a' et la chaine dans 'temp' ?

certes on avance l'adresse de destination du stockage des données qui
arrivent, mais imaginons que les données qui sont envoyee sont des membres
d'une autre structure, totalement différente... de taille différente...
comment recv va-t-elle se débrouiller ?

autre question, pourquoi doit-on faire un cast (char *) pour le buffer ?
pourquoi c'est pas void* au lieu de char * ?

et enfin, dans une fonction que je ferai, chargée de recevoir proprement des
données, comment faire pour qu'elle soit "générale" pour tout mon programme,
càd que le buffer puisse etre de types différents ?

je propose

int recevoir (void *buffer, size_t buflen)
{
int total_lu,lu;

for(total_lu=0;total_lu<buflen
{
lu=recv(my_sock,(char *)(&buffer)+total_lu,sizeof(buffer)-lu);
if (lu!=SOCKET_ERROR)
total_lu+=lu;
else
{ /gestion d'erreur/ return MON_ERREUR_RECV; }
}

return 0;
}


et dans le programme on l'utiliserai en mettant n'importe quel type de
buffer, comme une structure par exemple... (faudrait-il faire un cast ?)


--
nico,
http://astrosurf.com/nicoastro
messenger : @hotmail.com
Avatar
Cyrille \cns\ Szymanski
> bon ok recv reçoit les données paquet par paquet... mais comment les
place-t-elle dans mon buffer ?



Il les copie à l'adresse mémoire demandée ?


par exemple si j'ai une structure qui contient deux membres : int a;


(blablabla)
différente... comment recv va-t-elle se débrouiller ?



Ces fonction s'en foutent, elles ne savent rien sur ce qui est transféré
et elles n'en ont rien à faire. C'est comme si tu me demandais comment
ReadFile() fait pour connaître l'encodage des fichiers.

Tu lis les données dans un buffer (un char[] si tu veux) et ensuite tu
fais un cast (par exemple) pour les interpréter.


autre question, pourquoi doit-on faire un cast (char *) pour le buffer
? pourquoi c'est pas void* au lieu de char * ?



Parce que le prototype de send() et recv() demande un char* ?


int recevoir (void *buffer, size_t buflen)
{
int total_lu,lu;

for(total_lu=0;total_lu<buflen
{
lu=recv(my_sock,(char *)(&buffer)+total_lu,sizeof(buffer)-lu);
if (lu!=SOCKET_ERROR)
total_lu+=lu;
else
{ /gestion d'erreur/ return MON_ERREUR_RECV; }
}

return 0;
}



C'est déjà beaucoup mieux ça.
J'éviterais de mélanger les size_t et les int : signed/unsigned =
problèmes.

--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/
Avatar
Nicolas aunai
Cyrille "cns" Szymanski a écrit:

Ces fonction s'en foutent, elles ne savent rien sur ce qui est
transféré et elles n'en ont rien à faire. C'est comme si tu me
demandais comment ReadFile() fait pour connaître l'encodage des
fichiers.



elles s'en foutent ok, alors que va-t-il se passer si les données reçues ne
sont pas conformes avec le buffer de stockage ? structures différentes par
exemple, plantage ??

autre question, pourquoi doit-on faire un cast (char *) pour le
buffer ? pourquoi c'est pas void* au lieu de char * ?



Parce que le prototype de send() et recv() demande un char* ?



super la réponse a deux balles... ça j'ai bien vu... mais pourquoi un
(char*) ?? pourquoi pas void* ?? void est fait pour ça, je vois pas
l'intéret du char....


C'est déjà beaucoup mieux ça.
J'éviterais de mélanger les size_t et les int : signed/unsigned > problèmes.



oui oui, c un truc fait vite fait avec le code de dominique copié... ma
fonction est différente.


--
nico,
http://astrosurf.com/nicoastro
messenger : @hotmail.com
Avatar
Dominique Vaufreydaz
Bonjour,

Nicolas aunai wrote:
elles s'en foutent ok, alors que va-t-il se passer si les données reçues ne
sont pas conformes avec le buffer de stockage ? structures différentes par
exemple, plantage ??



Ben tres certainement. C'est au programmeur de verifier ca pas
a la fonction de lecture. Tu lui demandes de lire x octets elle
le fait. A toi d'en faire bon usage.

autre question, pourquoi doit-on faire un cast (char *) pour le
buffer ? pourquoi c'est pas void* au lieu de char * ?


Parce que le prototype de send() et recv() demande un char* ?


super la réponse a deux balles... ça j'ai bien vu... mais pourquoi un
(char*) ?? pourquoi pas void* ?? void est fait pour ça, je vois pas
l'intéret du char....



Parceque c'est historique. char * etait le pointeur de tout type
de memoire en C. Donc voila, de nombreuses fonctions
utilisent char * comme type de pointeur generique. L'autre
avantage c'est que faire ++ sur un char * avance de 1 octet
en memoire.

Voila. Doms.
--
Impose ta chance, serre ton bonheur et va vers ton risque.
A te regarder, ils s'habitueront.
René Char, Les Matinaux.
----
http://www-prima.inrialpes.fr/Vaufreydaz/
http://slmg.imag.fr/
http://slmg-index.imag.fr/
http://TitchKaRa.free.fr/
http://logiciels.ntfaqfr.com/
1 2