-
Socket, Select + Peek ?
Bonjour,
Je cherche à pouvoir lire un message d'une socket, dans sa totalité. J'utilise un select sur le file descriptor et une socket non bloquante. Le select m'indique que des données ont été écrite. Cependant, il arrive de temps en temps que je ne puisse récupérer la totalité des octets, car ceux ci ne sont pas tous disponibles. Du coup, le recv ne retourne pas le nombre attendu.
Donc, j'utilise un select, suivi d'un recv avec option PEEK, qui n'enlève pas les données de la socket. Dès que le recv option PEEK retourne le nombre d'octets attendu, j'utilise le recv sans l'option PEEK.
Y'a t-il un autre moyen de réaliser ce type d'opération ? Il y a je crois le recv avec l'option MSG_WAITALL mais du coup il se peut que je reste bloqué tout le temps.
Julien.
-
Visiblement, tu utilises un socket de type STREAM (style TCP), alors que tu voudrais un socket de type DATAGRAM (à la UDP).
Dans le premier cas, les octets arrivent les uns à la suite des autres, et tu les lis au fur et à mesure que tu appelles recv(), un peu comme si c'était un fichier et la fonction read().
Dans le deuxième cas, les octets arrivent par "messages". Chaque message correspond à un envoi via send() ou sendto(), et l'autre partie le recupère via recv ou recvfrom comme un objet "atomique". Le récepteur ne reçoit rien tant que tout n'est pas arrivé.
-
Exact, j'utilise une socket TCP. Effectivement, je pourrais basculer vers du UDP mais je ne peux pas me permettre de "perdre" des paquets. Y'a t-il une autre solution en utilisant les sockets TCP ?
Julien.
-
MSG_WAITALL va effectivement attendre que le nombre d'octets que tu attends arrive. Tu peux utiliser setsockopt() avec un SO_RCVTIMEO ou je ne sais plus trop comment s'appelle ce flag pour spécifier un timeout.
J'admets que ce n'est pas exactement ce que tu cherches : l'idéal dans ton cas serait d'attendre qu'un certain nombre d'octets soit dispo sur ce socket avant de le lire, mais là perso je ne vois pas. J'avais trouvé une fonction qui permettait de savoir combien d'octets sont dispo à la lecture, mais je suis incapable d'y remettre la main dessus, et ce n'est pas l'idéal dans ton cas.
-
Ah je vais quand même tester le MSG_WAITALL avec le timeout.
Merci Phi !
Julien.