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

que fait exactement la fonction recv des sockets.

8 réponses
Avatar
WebShaker
bon je ne suis pas trop callé en socket, mais j'aimerai savoir quel est
l'impact de la taille du buffer dans le fonction recv

int dl_block = 512;

while (size != 0)
{
err = recv(sock, page, dl_block, 0);
page += dl_block;
}

J'explique un peu plus mon problème.
Je développe un truc qui va utiliser une connexion EDGE.
je réalise le téléchargement des données via un thread, ce qui me permet
avec un peu d'effort de commencer à analyser les données reçues dès
avant d'avoir la totalité du fichier.

Donc j'aurai envie de réduire au maximum dl_block afin de pouvoir
commencer plus tôt le travail.

Ce que j'aimerai savoir c'est s'il y a moyen de trouver la bonne valeur
pour dl_block ?
Et si en terme de réseau il y a des échanges qui se font à chaque fois
que j'appelle la fonction recv (hors transfert des données) et qui donc
pourrait militer en faveur de block plus gros pour un nombre d'appels
moins grand !!!

Merci.
Etienne

8 réponses

Avatar
espie
In article <4d18d1ee$0$27510$,
WebShaker wrote:
bon je ne suis pas trop callé en socket, mais j'aimerai savoir quel est
l'impact de la taille du buffer dans le fonction recv

int dl_block = 512;

while (size != 0)
{
err = recv(sock, page, dl_block, 0);
page += dl_block;
}

J'explique un peu plus mon problème.
Je développe un truc qui va utiliser une connexion EDGE.
je réalise le téléchargement des données via un thread, ce qui me permet
avec un peu d'effort de commencer à analyser les données reçues dès
avant d'avoir la totalité du fichier.

Donc j'aurai envie de réduire au maximum dl_block afin de pouvoir
commencer plus tôt le travail.

Ce que j'aimerai savoir c'est s'il y a moyen de trouver la bonne valeur
pour dl_block ?
Et si en terme de réseau il y a des échanges qui se font à chaque fois
que j'appelle la fonction recv (hors transfert des données) et qui donc
pourrait militer en faveur de block plus gros pour un nombre d'appels
moins grand !!!

Merci.
Etienne



Normalement, recv te rend la main des qu'il y a des donnees qui te sont
arrivees. C'est d'ailleurs pour cela que ca te donne un peu plus que juste
un code d'erreur, mais bien la quantite de donnees recues.

Ton code est faux, et pas qu'un peu.
Independamment de ce que tu veux faire, ca serait plus du:

int dl_block = 512;

do
{
sz = recv(sock, page, dl_block, 0);
if (sz == -1) {
throw something;
}
page += sz;
} while (err != 0);

e.g., c'est bloquant si tu socket est bloquante, mais il suffit qu'il y ait
des choses arrivees pour que ca te donne quelque chose.


C'est tres suffisant en general. On peut parametrer les choses differemment,
surtout en rendant la socket non bloquante, ou en jouant avec select/poll,
mais aussi en jouant avec setsockopt, tout particulierement, SO_RCVLOWAT,
SO_RCVTIMEO, SO_RCVBUF (ca, ca peut etre sympa si on attend de gros bursts
de donnees et qu'on risque de prendre du temps a les traiter).
Avatar
WebShaker
Le 27/12/2010 19:43, Marc Espie a écrit :
Ton code est faux, et pas qu'un peu.
Independamment de ce que tu veux faire, ca serait plus du:

int dl_block = 512;

do
{
sz = recv(sock, page, dl_block, 0);
if (sz == -1) {
throw something;
}
page += sz;
} while (err != 0);



Oui c'est exact.
c'est mieux comme ca :)

e.g., c'est bloquant si tu socket est bloquante, mais il suffit qu'il y ait
des choses arrivees pour que ca te donne quelque chose.

C'est tres suffisant en general. On peut parametrer les choses differemment,
surtout en rendant la socket non bloquante, ou en jouant avec select/poll,
mais aussi en jouant avec setsockopt, tout particulierement, SO_RCVLOWAT,
SO_RCVTIMEO, SO_RCVBUF (ca, ca peut etre sympa si on attend de gros bursts
de donnees et qu'on risque de prendre du temps a les traiter).



bon je vais regarder ce que je trouve.
merci.

Etienne
Avatar
Michael Doubez
On 27 déc, 18:50, WebShaker wrote:
bon je ne suis pas trop call en socket, mais j'aimerai savoir quel est
l'impact de la taille du buffer dans le fonction recv



Je suppose que la question est "autre que la quantité de données que
la fonction te retourne". Pas grand chose sauf qu'un petit buffer
multiplie le nombre d'appel à recv est de copies dans ton buffer.

L'OS conserve des données reçues dans un buffer interne jusqu'à ce qu e
tu en aies besoin. C'est la taille de ce buffer là qui peut faire une
différence.

[snip] code corrigé elsethread



[snip] discutté elsethread select/O_NONBLOCK
Ce que j'aimerai savoir c'est s'il y a moyen de trouver la bonne valeur
pour dl_block ?



Ca dépends de la couche application, si tu reconstitue le buffer par
la suite à ça importe peu; et si tu reçoit par trame il suffit que tu
aies la taille du message maximal.

Un read de 1 octet à chaque fois n'est pas forcément choquant mais pas
très efficace.

Et si en terme de r seau il y a des changes qui se font chaque fois
que j'appelle la fonction recv (hors transfert des donn es) et qui donc
pourrait militer en faveur de block plus gros pour un nombre d'appels
moins grand !!!



Non, recv n'est qu'une interface avec l'OS et est plus ou moins
déconnecté du protocole sous jacent (à moins que tu ne travailles en
zero-copy). Par contre, tu sollicites un appel système donc c'est
couteux.

--
Michael
Avatar
WebShaker
Le 28/12/2010 10:56, Michael Doubez a écrit :
On 27 déc, 18:50, WebShaker wrote:

Ca dépends de la couche application, si tu reconstitue le buffer par
la suite à ça importe peu; et si tu reçoit par trame il suffit que tu
aies la taille du message maximal.



Bon.

Un read de 1 octet à chaque fois n'est pas forcément choquant mais pas
très efficace.



Ah ok.
Rien que cette phrase répond a toute ma question.

Et si en terme de r seau il y a des changes qui se font chaque fois
que j'appelle la fonction recv (hors transfert des donn es) et qui donc
pourrait militer en faveur de block plus gros pour un nombre d'appels
moins grand !!!



Non, recv n'est qu'une interface avec l'OS et est plus ou moins
déconnecté du protocole sous jacent (à moins que tu ne travailles en
zero-copy). Par contre, tu sollicites un appel système donc c'est
couteux.



Super.
Merci.

Surtout que j'ai un peu regardé select et pool, et j'ai rien compris,
j'ai plutôt le sensation que les gens l'utilisent avec les applis serveur.

Moi c'est un client tout bête.

Etienne
Avatar
espie
In article <4d19f2fb$0$5881$,
WebShaker wrote:
Surtout que j'ai un peu regardé select et pool, et j'ai rien compris,
j'ai plutôt le sensation que les gens l'utilisent avec les applis serveur.



Non, ils s'en servent des qu'ils doivent multiplexer des entrees-sorties
sur plusieurs flux.

Moi c'est un client tout bête.



Eh bien, fais du recv() tout bete, ca marche tres bien pour les cas simples.
Tu n'auras besoin de code plus complexe que lorsque tu auras besoin de
voir s'il traine des donnees sur ta socket sans necessairement dormir a ce
moment-la.
Avatar
Michael Doubez
On 28 déc, 16:13, (Marc Espie) wrote:
In article <4d19f2fb$0$5881$,

WebShaker   wrote:
>Surtout que j'ai un peu regardé select et pool, et j'ai rien compris,
>j'ai plutôt le sensation que les gens l'utilisent avec les applis serv eur.

Non, ils s'en servent des qu'ils doivent multiplexer des entrees-sorties
sur plusieurs flux.



Ou alors si ils ont besoin d'un timeout sur la réception de donnée, ce
qui est généralement une bonne idée.

A ce propos, SO_RCVTIMEO que tu as mentionné est un setsockopt en
lecture seule. Concernant, les SO_*LOWAT, ils paramètrent les
watermarks pour éviter le "silly window syndrome"; c'est assez
particulier, je ne connais pas d'exemple pratique de tuning sur ce
paramètre.

--
Michael
Avatar
espie
In article ,
Michael Doubez wrote:
On 28 déc, 16:13, (Marc Espie) wrote:
In article <4d19f2fb$0$5881$,

WebShaker   wrote:
>Surtout que j'ai un peu regardé select et pool, et j'ai rien compris,
>j'ai plutôt le sensation que les gens l'utilisent avec les applis serveur.

Non, ils s'en servent des qu'ils doivent multiplexer des entrees-sorties
sur plusieurs flux.



Ou alors si ils ont besoin d'un timeout sur la réception de donnée, ce
qui est généralement une bonne idée.



Ca depend. Ca impose quand meme d'avoir beaucoup plus de code, et de
savoir ce que tu fais lorsque tu te prends un timeout...

La gestion d'erreurs, c'est toujours complique, rarement suffisamment
teste, et c'est toujours la que tu vas trouver les bugs qui vont te pourrir
ton logiciel. Particulierement cote securite. En plus, on parle d'un soft
reseau, la... (enfin bon, le posteur original avait regarde en diagonale
le fonctionnement de recv, je ne donne pas cher de son code cote robustesse).

On pourrait penser que les exceptions vont simplifier la chose, sauf que
la litterature sur le sujet (Sutter) montre assez nettement que... ca
reste toujours tres complique. Peut-etre un tantinet moins penible a
organiser, mais toujours difficile a faire marcher convenablement.
Il semble bien que l'esprit humain a du mal a valider plusieurs chemins dans
le meme code simultanement.
Avatar
Michael Doubez
On 30 déc, 11:58, (Marc Espie) wrote:
In article .com>,
Michael Doubez   wrote:

>On 28 d c, 16:13, (Marc Espie) wrote:
>> In article <4d19f2fb$0$5881$,

>> WebShaker wrote:
>> >Surtout que j'ai un peu regard select et pool, et j'ai rien compris,
>> >j'ai plut t le sensation que les gens l'utilisent avec les applis ser veur.

>> Non, ils s'en servent des qu'ils doivent multiplexer des entrees-sorti es
>> sur plusieurs flux.

>Ou alors si ils ont besoin d'un timeout sur la r ception de donn e, ce
>qui est g n ralement une bonne id e.

Ca depend. Ca impose quand meme d'avoir beaucoup plus de code, et de
savoir ce que tu fais lorsque tu te prends un timeout...



Justement, c'est plutôt bien de se poser la question plutôt que
d'attendre 3 minutes que la couche TCP te renvoie une erreur.

De plus, il est bien de fournir un état d'avancement (même si c'est
pour dire que rien n'a été fait) de façon à ce que l'utilisateur
puisse estimer le temps d'attente et/ou localiser un problème. Ou au
moins lui dire que le programme n'est pas gelé et éviter un CTRL+C
intempestif.

La gestion d'erreurs, c'est toujours complique, rarement suffisamment
teste, et c'est toujours la que tu vas trouver les bugs qui vont te pourr ir
ton logiciel. Particulierement cote securite. En plus, on parle d'un soft
reseau, la... (enfin bon, le posteur original avait regarde en diagonale
le fonctionnement de recv, je ne donne pas cher de son code cote robustes se).



C'est un point à débattre mais même dans ce cas, fournir un minimum
d'information fait gagner du temps à l'utilisation (ce qu'on peut
supposer comme représentant plus de temps que le développement).

On pourrait penser que les exceptions vont simplifier la chose, sauf que
la litterature sur le sujet (Sutter) montre assez nettement que... ca
reste toujours tres complique. Peut-etre un tantinet moins penible a
organiser, mais toujours difficile a faire marcher convenablement.
Il semble bien que l'esprit humain a du mal a valider plusieurs chemins d ans
le meme code simultanement.



Écrire du code exception safe n'est qu'une partie du problème; ça
demande des outils mais on voit bien que C++ va dans ce sens: exprimer
le temps de vie dans un concept (ex: scoped_*) et il fournit même
aujourd'hui les erreurs système sous forme d'exception (ce qui est
mieux que errno).

Le point est plutôt qu'on a rangé dans une même catégorie des
évènements exceptionnels et des événements à traiter dans un flux
normal d'exécution (typiquement le succès d'une connexion).

Je n'ai pas encore regardé le système d'error_condition et
d'équivalence d'erreur de c++0x; il y a peut être quelque chose à
creuser par là.

--
Michael