Bien programmer en langage C
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Le Deal du moment : -17%
Casque de réalité virtuelle Meta Quest 2 ...
Voir le deal
249.99 €

Assurer la réception d'un message UDP

2 participants

Aller en bas

Assurer la réception d'un message UDP Empty Assurer la réception d'un message UDP

Message  Davidlouiz Ven 25 Juin 2010 - 22:36

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.

Davidlouiz
Bavard
Bavard

Messages : 10
Date d'inscription : 27/05/2008

Revenir en haut Aller en bas

Assurer la réception d'un message UDP Empty Re: Assurer la réception d'un message UDP

Message  -ed- Dim 27 Juin 2010 - 17:54

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.

-ed-
-ed-
Admin
Admin

Messages : 290
Date d'inscription : 26/05/2008
Age : 67
Localisation : Paris 14eme arrondissement (75, France)

http://bien-programmer.fr

Revenir en haut Aller en bas

Assurer la réception d'un message UDP Empty Re: Assurer la réception d'un message UDP

Message  Davidlouiz Sam 11 Juin 2011 - 5:44

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
Bavard

Messages : 10
Date d'inscription : 27/05/2008

Revenir en haut Aller en bas

Assurer la réception d'un message UDP Empty Re: Assurer la réception d'un message UDP

Message  -ed- Sam 11 Juin 2011 - 5:48

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
-ed-
-ed-
Admin
Admin

Messages : 290
Date d'inscription : 26/05/2008
Age : 67
Localisation : Paris 14eme arrondissement (75, France)

http://bien-programmer.fr

Revenir en haut Aller en bas

Assurer la réception d'un message UDP Empty Re: Assurer la réception d'un message UDP

Message  Davidlouiz Jeu 2 Oct 2014 - 4:20

-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
Bavard

Messages : 10
Date d'inscription : 27/05/2008

Revenir en haut Aller en bas

Assurer la réception d'un message UDP Empty Re: Assurer la réception d'un message UDP

Message  -ed- Jeu 2 Oct 2014 - 9:01

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 !
-ed-
-ed-
Admin
Admin

Messages : 290
Date d'inscription : 26/05/2008
Age : 67
Localisation : Paris 14eme arrondissement (75, France)

http://bien-programmer.fr

Revenir en haut Aller en bas

Assurer la réception d'un message UDP Empty Re: Assurer la réception d'un message UDP

Message  Davidlouiz Jeu 2 Oct 2014 - 15:50

D'accord. C'est parfait ! :)

Merci d'avoir répondu si vite.

Davidlouiz
Bavard
Bavard

Messages : 10
Date d'inscription : 27/05/2008

Revenir en haut Aller en bas

Assurer la réception d'un message UDP Empty Re: Assurer la réception d'un message UDP

Message  Davidlouiz Ven 24 Oct 2014 - 3:28

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
Bavard

Messages : 10
Date d'inscription : 27/05/2008

Revenir en haut Aller en bas

Assurer la réception d'un message UDP Empty Re: Assurer la réception d'un message UDP

Message  -ed- Ven 24 Oct 2014 - 7:05

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 ...

Assurer la réception d'un message UDP Trames

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
-ed-
-ed-
Admin
Admin

Messages : 290
Date d'inscription : 26/05/2008
Age : 67
Localisation : Paris 14eme arrondissement (75, France)

http://bien-programmer.fr

Revenir en haut Aller en bas

Assurer la réception d'un message UDP Empty Re: Assurer la réception d'un message UDP

Message  Contenu sponsorisé


Contenu sponsorisé


Revenir en haut Aller en bas

Revenir en haut

- Sujets similaires

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum
Ne ratez plus aucun deal !
Abonnez-vous pour recevoir par notification une sélection des meilleurs deals chaque jour.
IgnorerAutoriser