Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

10 réponses

1 2
Avatar
Cyrille \cns\ Szymanski
> par exemple quand j'utilise recv() je fais :

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



Faux !
Il faut déplacer le pointeur en fonction du nombre d'octets envoyés.

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



Donc tu dois les compter, et ça te dira quand tout aura été envoyé. Et bien
sûr prendre en compte les codes d'erreur.


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 ?



sic.

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


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



Faux !
Il faut déplacer le pointeur en fonction du nombre d'octets envoyés.



quoi ???

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



Donc tu dois les compter, et ça te dira quand tout aura été envoyé.
Et bien sûr prendre en compte les codes d'erreur.



??


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 ?



sic.




???


--
nico,
http://astrosurf.com/nicoastro
messenger : @hotmail.com
Avatar
Cyrille \cns\ Szymanski
>>> do{
result=recv(my_sock,(char *)&structure,sizeof(structure),0);
}
while(result<=0);



Faux !
Il faut déplacer le pointeur en fonction du nombre d'octets envoyés.



quoi ???



Voyons, concentre-toi un peu...

S'il a deja reçu n octets la fois d'avant, tu lui en demandes encore sizeof
(structure) ?
Où recv va-t-il mettre les données qu'il vient de recevoir au deuxième
appel (s'il est appelé plusieurs fois) ?
etc.


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



Donc tu dois les compter, et ça te dira quand tout aura été envoyé.
Et bien sûr prendre en compte les codes d'erreur.



??



Es-tu certain que la condition de sortie de la boucle est satisfaisante ?
(A mon avis elle devrait être quelquechose du genre "sortir de la boucle
quand on a reçu sizeof(stricture) octets", non ?)


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


Il faut déplacer le pointeur en fonction du nombre d'octets envoyés.



quoi ???



Voyons, concentre-toi un peu...



arrete de me prendre pour un abruti aussi....

S'il a deja reçu n octets la fois d'avant, tu lui en demandes encore
sizeof (structure) ?
Où recv va-t-il mettre les données qu'il vient de recevoir au deuxième
appel (s'il est appelé plusieurs fois) ?
etc.



aucune idée car :

1) je ne sais pas comment marche recv, je veux dire comment elle reçoit les
données (en entier ? par morceaux..? etc..)

2) j'ai supposé que s'il y avait une erreur de reception ça écrasait le
contenu de la structure pour remettre la nouvelle reception, et ainsi
jusqu'à ce que ça soit bien reçu en entier... j'en c rien moi...

et d'aileurs, pourquoi que ça marcherai pas ??



Es-tu certain que la condition de sortie de la boucle est
satisfaisante ? (A mon avis elle devrait être quelquechose du genre
"sortir de la boucle quand on a reçu sizeof(stricture) octets", non ?)




pourquoi je ne recevrai pas toutes les données ??


--
nico,
http://astrosurf.com/nicoastro
messenger : @hotmail.com
Avatar
Dominique Baldo
Nicolas aunai nous disait

> S'il a deja reçu n octets la fois d'avant, tu lui en demandes encore
> sizeof (structure) ?
> Où recv va-t-il mettre les données qu'il vient de recevoir au deuxième
> appel (s'il est appelé plusieurs fois) ?
> etc.

aucune idée car :

1) je ne sais pas comment marche recv, je veux dire comment elle reçoit les
données (en entier ? par morceaux..? etc..)



Read The Fine Manual (RTFM ®)

recv:
int recv (
SOCKET s,
char FAR* buf,
int len,
int flags
);
--
as much information as is currently available **UP TO** the size len of
the buffer supplied is returned

Return Values:
If no error occurs, recv returns the number of bytes received.Otherwise,
a value of SOCKET_ERROR is returned
--
Si tu lis pas l'anglais ca dit que ca renvoi **jusqu'à** (de chez
inférieur ou égal) "len" octets dans le buffer buf, et que le int
retourné est précisément ce nombre d'octets lu ou SOCKET_ERROR en cas
d'erreur (déconnexion sauvage ou timeout)

donc en gros ce qu'il faut que tu fasses:

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

écrit salement (mais le principe de base y est)
Avatar
Dominique Baldo
précédemment j'écrivais:
lu=recv(my_sock,(char *)(&structure)+total_lu,sizeof(structure)-lu);



lu=recv(my_sock,(char *)(&structure)+total_lu,
sizeof(structure)-total_lu);

plutot :o)
Avatar
Nicolas aunai
Dominique Baldo a écrit:
précédemment j'écrivais:
lu=recv(my_sock,(char
*)(&structure)+total_lu,sizeof(structure)-lu);



lu=recv(my_sock,(char *)(&structure)+total_lu,
sizeof(structure)-total_lu);

plutot :o)




oui alors ok mais je comprend toujours pas ce qui se passe entre le send et
le recv, pourquoi ça marche alors ce que je faisais s'il faut faire avancer
le pointeur comme ça ? pourquoi ça peut se transmettre d'un seul bloc ou pas
?


--
nico,
http://astrosurf.com/nicoastro
messenger : @hotmail.com
Avatar
Dominique Baldo
Nicolas aunai nous disait
Dominique Baldo a écrit:
> précédemment j'écrivais:
>> lu=recv(my_sock,(char
>> *)(&structure)+total_lu,sizeof(structure)-lu);
>
> lu=recv(my_sock,(char *)(&structure)+total_lu,
> sizeof(structure)-total_lu);
>
> plutot :o)


oui alors ok mais je comprend toujours pas ce qui se passe entre le send et
le recv, pourquoi ça marche alors ce que je faisais s'il faut faire avancer
le pointeur comme ça ? pourquoi ça peut se transmettre d'un seul bloc ou pas
?



ca dépend de l'encombrement du réseau, de la taille de ta structure et
de la taille max du paquet IP (adapté généralement à la nature de la
liaison physique: ppp sur téléphone, ethernet, liaison série ...)

en gros si le réseau et/ou ton PC (ou ta station) n'a que ça à foutre il
passera ton message en un seul coup (et si la structure ne dépasse pas
la taille max du paquet IP)

mais c'est pas garanti: si tu ouvres 30 autres connexions avec des gros
débits ou que tu bosses sur un réseau chargé (le collègue qui imprime
son poster de yasmin bleeth en 5000x4000 sur l'imprimante du coin) tu
risque de te faire saucisonner ton envoi en x petits paquets
élémentaires, un paquet peut mettre du temps à trouver sa destination si
bien que quand tu lis à l'autre bout t'es obligé de faire n lectures.

en pratique si ta structure ne fait que quelques octets il y a peu de
chance que ca foire ... mais ca pourrait.
Avatar
Cyrille \cns\ Szymanski
> oui alors ok mais je comprend toujours pas ce qui se passe entre le
send et le recv, pourquoi ça marche alors ce que je faisais s'il faut
faire avancer le pointeur comme ça ? pourquoi ça peut se transmettre
d'un seul bloc ou pas ?



Ben là c'est, disons le commandement numéro deux du programmeur :
"Ce n'est pas parce que ça marche que le code n'a pas de bug".
Le premier commandemant est (voir plus bas) :
"Je lirai la doc".
Et le troisième est :
"Je ne demanderai pas comment fonctionne la fonction xxxx quand sont
fonctionnement est décrit dans la doc".

En fait dans ton cas ça n'a pas planté parce que tu dois tester ça en
réseau local et que pour les raisons que donne Dominique il ne saucissonne
pas ta structure, ie. la boucle n'est exécutée qu'une seule fois.

Si elle l'était deux fois ou plus, bonjour les dégâts...


PS: Peux-tu bannir les expressions du type "je ne sais pas comment marche
<fonction xxx>" lorsque son fonctionnement est décrit dans la doc. Dans le
même ordre d'idée il y a "j'ai supposé que <blablabla>" lorsque blablabla
n'est pas écrit dans la doc.

Bon ok, c'est pas sympa comme remarque, je suis un pauvre con frustré et je
ne suis pas gentil mais je t'ai aidé....

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

Ben là c'est, disons le commandement numéro deux du programmeur :
"Ce n'est pas parce que ça marche que le code n'a pas de bug".
Le premier commandemant est (voir plus bas) :
"Je lirai la doc".
Et le troisième est :
"Je ne demanderai pas comment fonctionne la fonction xxxx quand
sont fonctionnement est décrit dans la doc".



et alors ? c pas pour ça que j'ai pensé a faire ce truc de l'adresse qui
change etc...
on a qd même le droit de demander, je vois pas qui ça gêne, et si ça gêne on
répond pas voilà tout.



En fait dans ton cas ça n'a pas planté parce que tu dois tester ça en
réseau local et que pour les raisons que donne Dominique il ne
saucissonne pas ta structure, ie. la boucle n'est exécutée qu'une
seule fois.

Si elle l'était deux fois ou plus, bonjour les dégâts...




ok


PS: Peux-tu bannir les expressions du type "je ne sais pas comment
marche <fonction xxx>" lorsque son fonctionnement est décrit dans la
doc. Dans le même ordre d'idée il y a "j'ai supposé que <blablabla>"
lorsque blablabla n'est pas écrit dans la doc.




c pas parce que c marqué comment ça marche dans la doc que tu sais forcément
qu'elle est la façon de coder le truc.


Bon ok, c'est pas sympa comme remarque, je suis un pauvre con frustré
et je ne suis pas gentil mais je t'ai aidé....



tout a fait !


--
nico,
http://astrosurf.com/nicoastro
messenger : @hotmail.com
1 2