Je peine à déceler l'origine d'un problème lié à l'utilisation des
sockets réseaux non-bloquants en tant que flux bufferisé. Peut être
aurez vous l'explication.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant:
fputs(data, dst);
fflush(dst);
Le problème est que je ne reçois pas toujours la totalité de ce que j'ai
envoyé. Si il y a des "trous" (un certain nombre de lignes consécutives
manquantes) alors la dernière ligne reçue est toujours incomplète.
Le problème commence à apparaître avec un nombre de lignes envoyées > à
20.000. En dessous de ce nombre, toutes les lignes envoyées sont reçues.
Tout cela m'amène à penser qu'il s'agit d'un problème lié au fait que le
buffer attribué à 'dst' est plein. Et qu'il se re-rempli bien plus vite
qu'il ne se vide. (Existe t-il d'ailleurs un moyen de connaître son taux
d'occupation ?)
Pendant toute la durée du traitement, fputs ne retourne jamais d'erreur.
Ce n'est pas le cas que fflush qui commence à renvoyer des EAGAIN à
répétition à l'approche des 20.000 lignes.
Le simple fait d'intercaler un sleep(3) après chaque erreur de fflush
suffit à limiter la perte à une ou deux lignes sur les 100.000.
En passant 'dst' en mode non-bufferisé ou bufferisé en ligne, _IONBF ou
_IOLBF, le problème est réglé. Mais j'aimerai comprendre ce qu'il se
passe dans le cas présenté pour ne pas mourir idiot.
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Marc Boyer
On 2009-04-21, Fançois Marc <none> wrote:
Bonjour,
Je peine à déceler l'origine d'un problème lié à l'utilisation des sockets réseaux non-bloquants en tant que flux bufferisé. Peut être aurez vous l'explication.
Je ne suis pas spécialiste de la question, mais en attendant que quelqu'un précise, quelques remarques.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant: fputs(data, dst); fflush(dst);
Le problème est que je ne reçois pas toujours la totalité de ce que j'ai envoyé. Si il y a des "trous" (un certain nombre de lignes consécutives manquantes) alors la dernière ligne reçue est toujours incomplète. Le problème commence à apparaître avec un nombre de lignes envoyées > à 20.000. En dessous de ce nombre, toutes les lignes envoyées sont reçues.
Tout d'abord, précisons que cela n'est pas un problème de C (d'où mon cross-post et fu2), mais lié aux sockets (et le fait que les socket aient une API en C ne signifie pas qu'ils soient du C). Je fais le fu2 vers fr.comp.os.unix car même s'il n'y a pas que là qu'il y a des sockets, historiquement, ils en viennent.
Tout cela m'amène à penser qu'il s'agit d'un problème lié au fait que le buffer attribué à 'dst' est plein. Et qu'il se re-rempli bien plus vite qu'il ne se vide.
Surement. Déjà, est-ce que tu as ouvert un socket UDP ou TCP ? En UDP, ton problème est normal (pas de controle de flux). Si ça apparait en TCP, c'est plus génant.
Marc Boyer -- Au XXIème siècle, notre projet de société s'est réduit à un projet économique...
On 2009-04-21, Fançois Marc <none> wrote:
Bonjour,
Je peine à déceler l'origine d'un problème lié à l'utilisation des
sockets réseaux non-bloquants en tant que flux bufferisé. Peut être
aurez vous l'explication.
Je ne suis pas spécialiste de la question, mais en attendant que
quelqu'un précise, quelques remarques.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant:
fputs(data, dst);
fflush(dst);
Le problème est que je ne reçois pas toujours la totalité de ce que j'ai
envoyé. Si il y a des "trous" (un certain nombre de lignes consécutives
manquantes) alors la dernière ligne reçue est toujours incomplète.
Le problème commence à apparaître avec un nombre de lignes envoyées > à
20.000. En dessous de ce nombre, toutes les lignes envoyées sont reçues.
Tout d'abord, précisons que cela n'est pas un problème de C (d'où mon
cross-post et fu2), mais lié aux sockets (et le fait que les socket aient
une API en C ne signifie pas qu'ils soient du C). Je fais le fu2 vers
fr.comp.os.unix car même s'il n'y a pas que là qu'il y a des sockets,
historiquement, ils en viennent.
Tout cela m'amène à penser qu'il s'agit d'un problème lié au fait que le
buffer attribué à 'dst' est plein. Et qu'il se re-rempli bien plus vite
qu'il ne se vide.
Surement.
Déjà, est-ce que tu as ouvert un socket UDP ou TCP ? En UDP, ton problème
est normal (pas de controle de flux). Si ça apparait en TCP, c'est plus
génant.
Marc Boyer
--
Au XXIème siècle, notre projet de société s'est réduit
à un projet économique...
Je peine à déceler l'origine d'un problème lié à l'utilisation des sockets réseaux non-bloquants en tant que flux bufferisé. Peut être aurez vous l'explication.
Je ne suis pas spécialiste de la question, mais en attendant que quelqu'un précise, quelques remarques.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant: fputs(data, dst); fflush(dst);
Le problème est que je ne reçois pas toujours la totalité de ce que j'ai envoyé. Si il y a des "trous" (un certain nombre de lignes consécutives manquantes) alors la dernière ligne reçue est toujours incomplète. Le problème commence à apparaître avec un nombre de lignes envoyées > à 20.000. En dessous de ce nombre, toutes les lignes envoyées sont reçues.
Tout d'abord, précisons que cela n'est pas un problème de C (d'où mon cross-post et fu2), mais lié aux sockets (et le fait que les socket aient une API en C ne signifie pas qu'ils soient du C). Je fais le fu2 vers fr.comp.os.unix car même s'il n'y a pas que là qu'il y a des sockets, historiquement, ils en viennent.
Tout cela m'amène à penser qu'il s'agit d'un problème lié au fait que le buffer attribué à 'dst' est plein. Et qu'il se re-rempli bien plus vite qu'il ne se vide.
Surement. Déjà, est-ce que tu as ouvert un socket UDP ou TCP ? En UDP, ton problème est normal (pas de controle de flux). Si ça apparait en TCP, c'est plus génant.
Marc Boyer -- Au XXIème siècle, notre projet de société s'est réduit à un projet économique...
espie
In article <49edb125$0$20526$, Fançois Marc <none> wrote:
Bonjour,
Je peine à déceler l'origine d'un problème lié à l'utilisation des sockets réseaux non-bloquants en tant que flux bufferisé. Peut être aurez vous l'explication.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant: fputs(data, dst); fflush(dst);
Tu n'as pas de garantie que la bibliotheque standard soit au courant des entrees-sorties non-bloquantes. Dans le code que j'ai sous la main, je vois des write(2), avec traitement uniforme de toutes les erreurs, et pas de cas particulier pour EGAIN, qui va donc remonter "tres vite" a l'utilisateur....
In article <49edb125$0$20526$426a74cc@news.free.fr>,
Fançois Marc <none> wrote:
Bonjour,
Je peine à déceler l'origine d'un problème lié à l'utilisation des
sockets réseaux non-bloquants en tant que flux bufferisé. Peut être
aurez vous l'explication.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant:
fputs(data, dst);
fflush(dst);
Tu n'as pas de garantie que la bibliotheque standard soit au courant des
entrees-sorties non-bloquantes. Dans le code que j'ai sous la main, je
vois des write(2), avec traitement uniforme de toutes les erreurs, et
pas de cas particulier pour EGAIN, qui va donc remonter "tres vite"
a l'utilisateur....
In article <49edb125$0$20526$, Fançois Marc <none> wrote:
Bonjour,
Je peine à déceler l'origine d'un problème lié à l'utilisation des sockets réseaux non-bloquants en tant que flux bufferisé. Peut être aurez vous l'explication.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant: fputs(data, dst); fflush(dst);
Tu n'as pas de garantie que la bibliotheque standard soit au courant des entrees-sorties non-bloquantes. Dans le code que j'ai sous la main, je vois des write(2), avec traitement uniforme de toutes les erreurs, et pas de cas particulier pour EGAIN, qui va donc remonter "tres vite" a l'utilisateur....
Fançois Marc
Marc Boyer wrote:
Tout d'abord, précisons que cela n'est pas un problème de C (d'où mon cross-post et fu2), mais lié aux sockets (et le fait que les socket aient une API en C ne signifie pas qu'ils soient du C). Je fais le fu2 vers fr.comp.os.unix car même s'il n'y a pas que là qu'il y a des sockets, historiquement, ils en viennent.
Merci pour le fu2, et désolé de ne pas y avoir pensé.
Déjà, est-ce que tu as ouvert un socket UDP ou TCP ? En UDP, ton problème est normal (pas de controle de flux). Si ça apparait en TCP, c'est plus génant.
Il s'agit d'un socket TCP.
Marc Boyer wrote:
Tout d'abord, précisons que cela n'est pas un problème de C (d'où mon
cross-post et fu2), mais lié aux sockets (et le fait que les socket aient
une API en C ne signifie pas qu'ils soient du C). Je fais le fu2 vers
fr.comp.os.unix car même s'il n'y a pas que là qu'il y a des sockets,
historiquement, ils en viennent.
Merci pour le fu2, et désolé de ne pas y avoir pensé.
Déjà, est-ce que tu as ouvert un socket UDP ou TCP ? En UDP, ton problème
est normal (pas de controle de flux). Si ça apparait en TCP, c'est plus
génant.
Tout d'abord, précisons que cela n'est pas un problème de C (d'où mon cross-post et fu2), mais lié aux sockets (et le fait que les socket aient une API en C ne signifie pas qu'ils soient du C). Je fais le fu2 vers fr.comp.os.unix car même s'il n'y a pas que là qu'il y a des sockets, historiquement, ils en viennent.
Merci pour le fu2, et désolé de ne pas y avoir pensé.
Déjà, est-ce que tu as ouvert un socket UDP ou TCP ? En UDP, ton problème est normal (pas de controle de flux). Si ça apparait en TCP, c'est plus génant.
Il s'agit d'un socket TCP.
-ed-
On 21 avr, 13:42, Fançois Marc <none> wrote:
Bonjour,
Je peine à déceler l'origine d'un problème lié à l'utilisation des sockets réseaux non-bloquants en tant que flux bufferisé. Peut être aurez vous l'explication.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant : fputs(data, dst); fflush(dst);
Quel intérêt de passer par les flux bufférisés ? On ajoute une couc he logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne 'normalement', c'est à dire avec recv() ?
On 21 avr, 13:42, Fançois Marc <none> wrote:
Bonjour,
Je peine à déceler l'origine d'un problème lié à l'utilisation des
sockets réseaux non-bloquants en tant que flux bufferisé. Peut être
aurez vous l'explication.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant :
fputs(data, dst);
fflush(dst);
Quel intérêt de passer par les flux bufférisés ? On ajoute une couc he
logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne
'normalement', c'est à dire avec recv() ?
Je peine à déceler l'origine d'un problème lié à l'utilisation des sockets réseaux non-bloquants en tant que flux bufferisé. Peut être aurez vous l'explication.
Soit 'sock' un socket non-bloquant:
FILE * dst = fdopen(sock, "r+");
Soit 'data' une ligne lue parmi 100.000 lignes, et une boucle exécutant : fputs(data, dst); fflush(dst);
Quel intérêt de passer par les flux bufférisés ? On ajoute une couc he logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne 'normalement', c'est à dire avec recv() ?
espie
In article , -ed- wrote:
Quel intérêt de passer par les flux bufférisés ? On ajoute une couche logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne 'normalement', c'est à dire avec recv() ?
Ca permet de reutiliser du code qui manipule directement des FILE *.... apres un moment, la reinvention de la roue, ca lasse.
In article <a1c48612-16d1-4949-9e64-182dfcac56ba@v15g2000yqn.googlegroups.com>,
-ed- <emmanuel.delahaye@gmail.com> wrote:
Quel intérêt de passer par les flux bufférisés ? On ajoute une couche
logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne
'normalement', c'est à dire avec recv() ?
Ca permet de reutiliser du code qui manipule directement des FILE *....
apres un moment, la reinvention de la roue, ca lasse.
Quel intérêt de passer par les flux bufférisés ? On ajoute une couche logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne 'normalement', c'est à dire avec recv() ?
Ca permet de reutiliser du code qui manipule directement des FILE *.... apres un moment, la reinvention de la roue, ca lasse.
-ed-
On 22 avr, 14:08, (Marc Espie) wrote:
In article .com>,
-ed- wrote: >Quel intérêt de passer par les flux bufférisés ? On ajoute une c ouche >logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne >'normalement', c'est à dire avec recv() ?
Ca permet de reutiliser du code qui manipule directement des FILE *.... apres un moment, la reinvention de la roue, ca lasse.
Bah, le traitement des réception par sockets ça se fait en une fonction que l'on classe dans sa bibliothèque perso... Pas besoin de passer par un fdopen() non portable qui ne fonctionnera pas sous Windows...
De plus, visiblement, ça introduit des comportements peu clairs ...
On 22 avr, 14:08, es...@lain.home (Marc Espie) wrote:
In article <a1c48612-16d1-4949-9e64-182dfcac5...@v15g2000yqn.googlegroups .com>,
-ed- <emmanuel.delah...@gmail.com> wrote:
>Quel intérêt de passer par les flux bufférisés ? On ajoute une c ouche
>logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne
>'normalement', c'est à dire avec recv() ?
Ca permet de reutiliser du code qui manipule directement des FILE *....
apres un moment, la reinvention de la roue, ca lasse.
Bah, le traitement des réception par sockets ça se fait en une
fonction que l'on classe dans sa bibliothèque perso... Pas besoin de
passer par un fdopen() non portable qui ne fonctionnera pas sous
Windows...
De plus, visiblement, ça introduit des comportements peu clairs ...
-ed- wrote: >Quel intérêt de passer par les flux bufférisés ? On ajoute une c ouche >logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne >'normalement', c'est à dire avec recv() ?
Ca permet de reutiliser du code qui manipule directement des FILE *.... apres un moment, la reinvention de la roue, ca lasse.
Bah, le traitement des réception par sockets ça se fait en une fonction que l'on classe dans sa bibliothèque perso... Pas besoin de passer par un fdopen() non portable qui ne fonctionnera pas sous Windows...
De plus, visiblement, ça introduit des comportements peu clairs ...
espie
In article , -ed- wrote:
On 22 avr, 14:08, (Marc Espie) wrote:
In article
,
-ed- wrote: >Quel intérêt de passer par les flux bufférisés ? On ajoute une couche >logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne >'normalement', c'est à dire avec recv() ?
Ca permet de reutiliser du code qui manipule directement des FILE *.... apres un moment, la reinvention de la roue, ca lasse.
Bah, le traitement des réception par sockets ça se fait en une fonction que l'on classe dans sa bibliothèque perso... Pas besoin de passer par un fdopen() non portable qui ne fonctionnera pas sous Windows...
De plus, visiblement, ça introduit des comportements peu clairs ...
Woah. Si tu veux traiter pas mal de protocoles classiques, c'est plutot bien d'avoir des entrees-sorties "classiques". Par contre, ca va plutot se gerer a coups de select qu'a coups d'entrees-sorties non bloquantes.
Pas portable sous windows ? en l'occurrence, rien a foutre. Si je veux du socket portable sous windows, je vais faire du perl de toutes facons
In article <e51baa56-d859-451e-95b0-56edf8b63489@q9g2000yqc.googlegroups.com>,
-ed- <emmanuel.delahaye@gmail.com> wrote:
On 22 avr, 14:08, es...@lain.home (Marc Espie) wrote:
-ed- <emmanuel.delah...@gmail.com> wrote:
>Quel intérêt de passer par les flux bufférisés ? On ajoute une couche
>logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne
>'normalement', c'est à dire avec recv() ?
Ca permet de reutiliser du code qui manipule directement des FILE *....
apres un moment, la reinvention de la roue, ca lasse.
Bah, le traitement des réception par sockets ça se fait en une
fonction que l'on classe dans sa bibliothèque perso... Pas besoin de
passer par un fdopen() non portable qui ne fonctionnera pas sous
Windows...
De plus, visiblement, ça introduit des comportements peu clairs ...
Woah. Si tu veux traiter pas mal de protocoles classiques, c'est plutot bien
d'avoir des entrees-sorties "classiques". Par contre, ca va plutot se gerer
a coups de select qu'a coups d'entrees-sorties non bloquantes.
Pas portable sous windows ? en l'occurrence, rien a foutre. Si je veux du
socket portable sous windows, je vais faire du perl de toutes facons
-ed- wrote: >Quel intérêt de passer par les flux bufférisés ? On ajoute une couche >logicielle. Est-ce bien nécessaire ? Est-ce que ça fonctionne >'normalement', c'est à dire avec recv() ?
Ca permet de reutiliser du code qui manipule directement des FILE *.... apres un moment, la reinvention de la roue, ca lasse.
Bah, le traitement des réception par sockets ça se fait en une fonction que l'on classe dans sa bibliothèque perso... Pas besoin de passer par un fdopen() non portable qui ne fonctionnera pas sous Windows...
De plus, visiblement, ça introduit des comportements peu clairs ...
Woah. Si tu veux traiter pas mal de protocoles classiques, c'est plutot bien d'avoir des entrees-sorties "classiques". Par contre, ca va plutot se gerer a coups de select qu'a coups d'entrees-sorties non bloquantes.
Pas portable sous windows ? en l'occurrence, rien a foutre. Si je veux du socket portable sous windows, je vais faire du perl de toutes facons