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

Lecture élémentaire d'une réponse réseau

2 réponses
Avatar
Fançois Marc
Je viens de renouer avec le C, et j'aurai besoin de votre avis sur
la manière de procéder à une lecture sur un flux réseau.

Le contexte est l'implémentation d'un protocole à message (type POP3).
Les réponses sont de longueur indéfinie, seul une suite de caractères
spécifiques marque la fin de la réponse. Ma question est donc la
suivante, comment réaliser la lecture d'une réponse complète de façon
propre.

Pour le moment, j'ai deux idées:
- Allocation d'un buffer de taille NB puis lecture des NB données du socket
- Si la marque de fin n'est pas trouvée, realloc() (taille actuelle + NB)
(lecture,recopie,etc) jusqu'à tomber sur la marque de fin.

Deuxième idée, sans trop savoir comment l'implémenter:
- Creer une fonction capable, à partir d'un file descriptor, de chercher
la présense d'une marque de fin et de retourner la taille nécessaire à
allouer pour tout stocker jusqu'a cette marque.
- Allocation de la taille retournée par la fonction et lecture du socket.

Le données provenant du réseau, elles peuvent mettre un certain temps
avant d'arriver. La deuxième méthode nécessiterait alors l'usage d'une
boucle car la marque de fin peut faire l'objet d'un n-ième paquet
n'étant pas encore arrivé au moment de l'appel de la fonction.
Pour les mêmes raisons, la première méthode nécessiterait aussi la prise
en compte du nombre d'octet lu et écrit à chaque appel afin de ne pas
ajouter systématiquement NB à chaque realloc(), mais plutôt NB moins
l'éventuel espace restant disponible.

Merci d'avance pour vos précieux conseils.

2 réponses

Avatar
espie
In article <49d9e7d3$0$29480$,
Fançois Marc <none> wrote:
Je viens de renouer avec le C, et j'aurai besoin de votre avis sur
la manière de procéder à une lecture sur un flux réseau.

Le contexte est l'implémentation d'un protocole à message (type POP3).
Les réponses sont de longueur indéfinie, seul une suite de caractères
spécifiques marque la fin de la réponse. Ma question est donc la
suivante, comment réaliser la lecture d'une réponse complète de façon
propre.



Si c'est un protocole de type pop3, pour de vrai, ben c'est oriente
ligne. En general, tu peux te contenter de fabrique un FILE * a partir
de ta connexion reseau (fdopen sur Unix) et de lire tes donnees a grands
coups de fgets... globalement, ca marche plutot bien. Ca demande juste
que le gugusse a l'autre bout ne fasse pas n'importe quoi.

Si c'est plus complique, toujours sous Unix, ca se fait a grands coups de
read sur ta socket, apres avoir pris soin de la passer en mode non-bloquant
pour eviter les soucis... Tu as des tonnes d'organisations possibles du
code.

Meme si ca peut sembler une bonne idee a premiere vue, s'amuser a decouper
le flux en messages que tu vas passer au niveau superieur va etre tres souvent
relativement inefficace (beaucoup de copies...). C'est souvent mieux de
meler ca a un parser correct, genere a grands coups de lex et de yacc, et de
ne gerer que les donnees a un niveau superieur...
Avatar
Fançois Marc
Marc Espie wrote:
Si c'est un protocole de type pop3, pour de vrai, ben c'est oriente
ligne. En general, tu peux te contenter de fabrique un FILE * a partir
de ta connexion reseau (fdopen sur Unix) et de lire tes donnees a grands
coups de fgets... globalement, ca marche plutot bien. Ca demande juste
que le gugusse a l'autre bout ne fasse pas n'importe quoi.



Tout d'abord, je tiens à vous remercier pour votre réponse.
Le passage d'un socket à un stream me permet effectivement de faire des
grands coups de fgets.

Cela dit, le serveur pouvant être amené à produire plusieurs lignes dans
sa réponse, j'ai dû rendre mon socket 'serveur' non-bloquant afin de
pouvoir boucler sur fgets() != NULL, et ainsi lire la totalité de la
réponse. La présence d'une réponse m'étant préalablement indiquée par
select().
Je ne sais pas si c'est la manière la plus élégante, mais ça fonctionne.