Assurer la réception d'un message UDP
2 participants
Page 1 sur 1
Assurer la réception d'un message UDP
Bonjour,
Dans le cadre du développement d'une application temps réel, j'ai besoin d'envoyer des messages à un serveur. Ces messages doivent parvenir au serveur le plus rapidement possible. L'ordre d'arrivé des messages n'a pas d'importance. Je pensais donc à utiliser UDP.
Mon problème, c'est qu'il s'agit de messages qui ne "doivent" pas être perdu. J'aimerai ne pas en perdre plus d'un sur 10 000 messages.
Je pensais donc à envoyer ces messages en 5 exemplaires à chaque fois. Le premier message valide qui arrive est décacheté. Mais j'ai peur qu'en cas de perte due à une congestion, cela ne fasse qu'empirer les choses.
Une autre solution consiste à créer une collection de message à envoyer. Lorsque je dois envoyer un message, je l'ajoute à la collection. Et une tâche se charge d'envoyer le courrier en boucle, de façon répétée et ne retire le message qu'après avoir reçu un accusé de réception.
Je voulais savoir s'il existe des mécanismes de ce genre permettant d'assurer la réception de message rapide/simple/efficace.
Merci.
Dans le cadre du développement d'une application temps réel, j'ai besoin d'envoyer des messages à un serveur. Ces messages doivent parvenir au serveur le plus rapidement possible. L'ordre d'arrivé des messages n'a pas d'importance. Je pensais donc à utiliser UDP.
Mon problème, c'est qu'il s'agit de messages qui ne "doivent" pas être perdu. J'aimerai ne pas en perdre plus d'un sur 10 000 messages.
Je pensais donc à envoyer ces messages en 5 exemplaires à chaque fois. Le premier message valide qui arrive est décacheté. Mais j'ai peur qu'en cas de perte due à une congestion, cela ne fasse qu'empirer les choses.
Une autre solution consiste à créer une collection de message à envoyer. Lorsque je dois envoyer un message, je l'ajoute à la collection. Et une tâche se charge d'envoyer le courrier en boucle, de façon répétée et ne retire le message qu'après avoir reçu un accusé de réception.
Je voulais savoir s'il existe des mécanismes de ce genre permettant d'assurer la réception de message rapide/simple/efficace.
Merci.
Davidlouiz- Bavard
- Messages : 10
Date d'inscription : 27/05/2008
Re: Assurer la réception d'un message UDP
Si le message est court, TCP est à la fois fiable et performant.
Sinon, UDP est très fiable mais l'ordre n'est pas garanti et un message peut être perdu. On peut implémenter un mécanisme de numérotation dans le message avec un checksum pour être sûr qu'il soit valide et le redemander en cas de problème. On peut aussi acquitter les messages reçus pour désengorger l'émetteur au fur et à mesure (car pour pouvoir renvoyer les messages, il doit les conserver en mémoire).
Conception d'un protocole à l'arrache :
Émetteur :
Émettre un message :
-Allouer un message
-Lui donner un nouveau numéro unique (absent du tableau d'indexation courant). La recherche se fait à partir du premier 'non libre'. On peut maintenir sa position dans une variable... Nota : par définition, l'adresse est un numéro unique ... Ca peut simplifier le mécanisme ...
-Calculer le checksum du message
-Placer le checksum dans le message
-Placer le numéro et l'adresse dans un tableau et le trier par numéro (indexation)
-Émettre le message, noter l'échéance (date + 2 ou 3 secondes max, selon granularité de la date) dans le tableau d'indexation. On peut aussi prévoir une purge automatique selon une date de fin de vie à date initiale + 20 ou 30 s, par exemple, avec log des messages non acquittés, pour statistiques de performance etc.
Dans la tâche de réception :
-Attendre l'acquittement (avec numéro du message)
-Si il est OK, retirer le message de la liste, remplacer le numéro par 0 ou -1, quelque chose qui veut dire 'libre'. Libérer le bloc, Trier le tableau d'index.
-Sil il est KO ou si le délai imparti est écoulé (si la date courante est >= à l'échéance, réémettre le message (noter la nouvelle échéance)
La surveillance de la date et l'évaluation des échéances se fait à chaque nouvel évènement de réception et par polling régulier (select() est idéal pour ça)
Nota. Comme l'adresse, la date peut être 'unique' si la granularité est suffisante ...
Récepteur :
Vérifier le checksum
OK -> renvoyer OK avec le numéro de message
KO -> renvoyer KO avec le numéro de message (en espérant que ce n'est pas lui qui est KO. Dans ce cas, on ne renvoie rien et le timer fera le travail.
Nota : une redondance triple est possible, par exemple le numéro est mis 3 fois dans le message émis. En cas de doute, on prend les 2 qui sont identiques. Si les trois sont différents, on ne renvoie rien et on attend que le timer tombe coté émission.
Avant de réinventer la roue (on est en gros en train de réécrire TCP ...) le mieux est de faire des essais en TCP pour mesurer les temps de réponse.
Sinon, UDP est très fiable mais l'ordre n'est pas garanti et un message peut être perdu. On peut implémenter un mécanisme de numérotation dans le message avec un checksum pour être sûr qu'il soit valide et le redemander en cas de problème. On peut aussi acquitter les messages reçus pour désengorger l'émetteur au fur et à mesure (car pour pouvoir renvoyer les messages, il doit les conserver en mémoire).
Conception d'un protocole à l'arrache :
Émetteur :
Émettre un message :
-Allouer un message
-Lui donner un nouveau numéro unique (absent du tableau d'indexation courant). La recherche se fait à partir du premier 'non libre'. On peut maintenir sa position dans une variable... Nota : par définition, l'adresse est un numéro unique ... Ca peut simplifier le mécanisme ...
-Calculer le checksum du message
-Placer le checksum dans le message
-Placer le numéro et l'adresse dans un tableau et le trier par numéro (indexation)
-Émettre le message, noter l'échéance (date + 2 ou 3 secondes max, selon granularité de la date) dans le tableau d'indexation. On peut aussi prévoir une purge automatique selon une date de fin de vie à date initiale + 20 ou 30 s, par exemple, avec log des messages non acquittés, pour statistiques de performance etc.
Dans la tâche de réception :
-Attendre l'acquittement (avec numéro du message)
-Si il est OK, retirer le message de la liste, remplacer le numéro par 0 ou -1, quelque chose qui veut dire 'libre'. Libérer le bloc, Trier le tableau d'index.
-Sil il est KO ou si le délai imparti est écoulé (si la date courante est >= à l'échéance, réémettre le message (noter la nouvelle échéance)
La surveillance de la date et l'évaluation des échéances se fait à chaque nouvel évènement de réception et par polling régulier (select() est idéal pour ça)
Nota. Comme l'adresse, la date peut être 'unique' si la granularité est suffisante ...
Récepteur :
Vérifier le checksum
OK -> renvoyer OK avec le numéro de message
KO -> renvoyer KO avec le numéro de message (en espérant que ce n'est pas lui qui est KO. Dans ce cas, on ne renvoie rien et le timer fera le travail.
Nota : une redondance triple est possible, par exemple le numéro est mis 3 fois dans le message émis. En cas de doute, on prend les 2 qui sont identiques. Si les trois sont différents, on ne renvoie rien et on attend que le timer tombe coté émission.
Avant de réinventer la roue (on est en gros en train de réécrire TCP ...) le mieux est de faire des essais en TCP pour mesurer les temps de réponse.
Re: Assurer la réception d'un message UDP
UDP est très fiable
Qu'entends-tu par fiable ?
Est-ce qu'un message transporté par UDP peut être modifié en cours de route ?
Davidlouiz- Bavard
- Messages : 10
Date d'inscription : 27/05/2008
Re: Assurer la réception d'un message UDP
Si une trame UDP est reçue, son contenu est correct. Si le contenu est erroné, la trame est rejetée et donc non reçue (du point de vue applicatif). C'est donc au protocole applicatif de gérer la continuité du message.
Dernière édition par -ed- le Jeu 2 Oct 2014 - 8:52, édité 1 fois
Re: Assurer la réception d'un message UDP
-ed- a écrit:Si une trame UDP est reçue, son contenu est correct.
Cela signifie-t-il que la réception d'un datagramme UDP de 512 octets est forcément le résultat de l'envoi d'un datagramme de 512 octets ?
Je me pose cette question car j'aimerais envoyer des datagrammes de 65507 octets comportant un en-tête. Ma crainte, c'est que le datagramme soit remis à la couche applicative du destinataire en plusieurs morceaux, si le MTU imposait une fragmentation, ce qui rendrait incohérent l'utilisation de l'en-tête. Mais peut-être qu'en cas de fragmentation, les morceaux sont systématiquement ré-assemblés avant d'être restitués à la couche applicative du destinataire.
Merci.
Davidlouiz- Bavard
- Messages : 10
Date d'inscription : 27/05/2008
Re: Assurer la réception d'un message UDP
Comme l'indique la définition de l'UDP, les datagrammes sont transmis de bout en bout quelque soient leur taille (la longueur est codée sur 16 bits). Par contre ni l'intégrité des données (perte d'un datagramme) ni l'ordre d'arrivée ne sont garantis.
Si des couches inférieures du protocole prennent l'initiative de faire du découpage, c'est leur problème et cela de nous regarde pas !
Si des couches inférieures du protocole prennent l'initiative de faire du découpage, c'est leur problème et cela de nous regarde pas !
Re: Assurer la réception d'un message UDP
D'accord. C'est parfait ! :)
Merci d'avoir répondu si vite.
Merci d'avoir répondu si vite.
Davidlouiz- Bavard
- Messages : 10
Date d'inscription : 27/05/2008
Re: Assurer la réception d'un message UDP
Davidlouiz a écrit:j'aimerais envoyer des datagrammes de 65507 octets
D'après mes tests, il semblerait que les datagrammes sont limité à 8192 octets (213). Or je pensais que la taille des datagramme était limité à 216 puisque le champs length de la couche IP est de 16 bits (voir RFC791).
Je suppose donc que 3 bits du champs length sont réservés à la fragmentation pour identifier les 6 morceaux lorsque le datagramme doit passer par un support dont le MTU est de 1500. Mais ce n'est qu'une supposition de ma part.
En savez vous plus à ce sujet ?
Merci.
Davidlouiz- Bavard
- Messages : 10
Date d'inscription : 27/05/2008
Re: Assurer la réception d'un message UDP
A ma connaissance, une taille de 65535 est possible pour un datagramme, mais c'est au niveau du protocole inférieur (IP, par exemple ou Ethernet sur un réseau local) qu'il peut y avoir du 'découpage'.
IPV4, par exemple limite la taille du datagramme à 65507 octets.
Par contre, une trame Ethernet est certes limitée à environ 1500 octets, mais cela est 'invisible' (ou transparent, question de point de vue !) vue de UDP ...
Concernant la limitation de la longueur des datagrammes, c'est peut être une caractéristique de l'émetteur. Il y a peut être un paramètre à régler genre 'Maximum Transmit Datagram Length' ...
Après quelques recherches, il semblerait effectivement que certains services réduisent la taille maximale des datagrammes ... Il va donc falloir un protocole 'au dessus' pour ré assembler les paquets ou revoir le design ...
Il sembler
IPV4, par exemple limite la taille du datagramme à 65507 octets.
Par contre, une trame Ethernet est certes limitée à environ 1500 octets, mais cela est 'invisible' (ou transparent, question de point de vue !) vue de UDP ...
Concernant la limitation de la longueur des datagrammes, c'est peut être une caractéristique de l'émetteur. Il y a peut être un paramètre à régler genre 'Maximum Transmit Datagram Length' ...
Après quelques recherches, il semblerait effectivement que certains services réduisent la taille maximale des datagrammes ... Il va donc falloir un protocole 'au dessus' pour ré assembler les paquets ou revoir le design ...
Il sembler
Page 1 sur 1
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum