Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Ordre d'arrivée des paquets en UDP /SOCKET


Sujet :

Réseau C

  1. #1
    Futur Membre du Club
    Ordre d'arrivée des paquets en UDP /SOCKET
    bonjour!
    Je reçois des information d'un système externe à mon pc, qui m'envoie une trame (numérote) toute les 4ms, j'arrive à les recevoir, ça pas de soucis ,mon problème qui vas vous paraître bizarre est que je veut recevoir la dernière trame émise et pas les trames dans l'ordre dans lesquelles elles sont envoyer, même si je perd des trames c'est "pas grave", je veut juste la dernière.

    si vous avez des pistes je suis preneur!!

    merci!

  2. #2
    Modérateur

    Bonjour,

    comment lis-tu les trames ?
    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  3. #3
    Futur Membre du Club
    salut !
    comme ça =
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
     
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
     
     
        if(sock !=-1)    // Configuration //
        {   memset((char *)&sinip, 0, sizeof(sinip));
            sinip.sin_addr.s_addr = inet_addr("192.168.1.4");//sin.sin_addr.s_addr = htonl(INADDR_ANY);  
            sinip.sin_family         = AF_INET;             // Protocole(TCP/IP)
            sinip.sin_port           = htons(PORT);         // Listage du port 
            sock_err = bind(sock, (SOCKADDR*)&sinip, sizeof(sinip));
        }
        if (sock_err==-1){if (pass==0){printf("La socket est pas encore connecté \n");pass=+1;}; connectsock=0;} 
        else{printf("La socket est maintenant ouverte en mode UDP \n");connectsock=1;}
     
     
    while(1)
        {
            int nb_octet = recvfrom(sock, buffer, sizeof(buffer), 0, (SOCKADDR*)&sinip, &fromlen); //reception de la data dans buffer
            //   printf("buffer= %s \n",buffer);
            //   printf("nb oct = %d \n",nb_octet);
     
                        char *dataM_X = rech(buffer,"<M_X>");
                        double M_X = atof(dataM_X);
                 ect ..... ect....
     
    if (selectionsujet==1)
        {
     
            printf("choix du sujet a configuré de 1 à 3\n");
            scanf("%d",&choix);
            printf("Entrez dist focus en mm\n");// futur input
            scanf("%d",&distfocus);
                        nb_octet = recvfrom(sock, buffer, sizeof(buffer), 0, (SOCKADDR*)&sinip, &fromlen); //reception de la data dans buffer
                        printf("nb oct = %d \n",nb_octet);
     
                  ect... ect....
         }
        }


    en fonctionnement normale je ne passe pas dans mon if donc j'arrive bien à toujours avoir la dernière trame car mon programme est plus rapide n'as pas de fonctions bloquantes(à par le recv si rien ne m'es envoyer), mais quand je passe dans dans mon if avec mon scanf je prend du retard et mon recv ne lis que la première trame depuis qu'il est en arrêt...

    en espérant que ça sois plus clair
    merci!

  4. #4
    Rédacteur/Modérateur

    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Futur Membre du Club
    oui j'ai bien un identifiant "IPOC" en fin de trame

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    <Rob Type="FANUC"><M_X>-1049.946</M_X><M_Y>-499.817</M_Y><M_Z>622.130</M_Z><M_W>-175.352966</M_W><M_P>89.161713</M_P><M_R>39.577858</M_R><F_X>-1049.946</F_X><F_Y>-499.817</F_Y><F_Z>622.130</F_Z><F_W>-175.352936</F_W><F_P>89.161720</F_P><F_R>39.577885</F_R><IPOStat>0</IPOStat><BMode>2</BMode><TRG>0</TRG><myRob>1</myRob><IPOC>1853552</IPOC></Rob>


    mais qand je met sur "pause" l'acquisition je stock tout les messages et quand je reprend la lecture je relis dans l'ordre d'arrivé les messages qui on été bloqué par ma pause.

    5>4>3>2>1||Pause||
    ||lecture||1>2>3>4>5
    au lieux e faire
    5>4>3>2>1||Pause||
    ||lecture||5>6>7ect..

  6. #6
    Rédacteur/Modérateur

    Bien, maintenant il faut lire la seconde partie du message
    Tu dois tout recevoir et ne garder que le plus récent à traiter.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  7. #7
    Expert éminent sénior
    Bonjour

    Dans l'absolu, chaque trame que tu reçois est toujours la "dernière". Tant que tu n'as pas reçu la suivante, la dernière à être arrivée est donc la dernière tout court.

    Donc en les traitant toutes, fatalement à un moment donné, la dernière que tu auras traitée sera celle que tu avais effectivement à traiter...
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  8. #8
    Futur Membre du Club
    si je vérifie si ma trame est bien ma dernière en gros je doit faire un truc du style (ce code est surement faux mais c'est histoire d'expliqué)
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    recvfrom(sock, buffer, sizeof(buffer), 0, (SOCKADDR*)&sinip, &fromlen); //reception de la data dans buffer
    dataIPOCprecedent= rech(buffer,"<IPOC>");//recherche dans la trame la valeur IPOC
    while (x=1)
    {
    recvfrom(sock, buffer, sizeof(buffer), 0, (SOCKADDR*)&sinip, &fromlen); //reception de la data dans buffer
    dataIPOC = rech(buffer,"<IPOC>");
    if (strcmp(dataIPOC,dataIPOCprecedent===0)
    {x=0;}
    else
    {dataIPOCprecedent=dataIPOC;}
    }


    mais si mon programme rester en pause 10min je vais avoir énormément de data a ouvrir et traiter dans mon while
    ce qui est un perte de temps énorme par rapport a quelque chose qui lirais juste la dernière data arrivé sur le pc..

  9. #9
    Expert éminent sénior
    Citation Envoyé par leoleo34 Voir le message
    ce qui est un perte de temps énorme par rapport a quelque chose qui lirais juste la dernière data arrivé sur le pc..
    Informatiquement (et d'ailleurs c'est aussi vrai dans la vie réelle), tu ne peux pas savoir qu'un élément est le "dernier" si tu ne le compares pas avec un autre. Quand tu lis un livre, tu ne sais que la dernière page est la dernière que parce qu'il n'y a pas de page après (en faisant abstraction évidemment de l'histoire qui se termine).
    Donc malheureusement tu es obligé de traiter tous tes éléments pour arriver à déterminer lequel est vraiment le dernier
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  10. #10
    Futur Membre du Club
    ok, je comprend le raisonnement, l'algo au dessus serais donc la meilleure solution?

  11. #11
    Rédacteur/Modérateur

    Tu as un nombre, pourquoi le comparer en string ?
    strcmp va vérifier qu'ils sont égaux ou différents, jamais lequel est plus récent. Et surtout si ton IPOC est vraiment un identifiant alors il doit incrémenter avec chaque envoi, donc comparer qu'il soit égale à un précédent reçu... ça a l'air bien inutile.
    Si tu mets tout dans buffer avant de vérifier, comment espères-tu pouvoir traiter autre chose que le dernier reçu ? Qui peut ne pas être le dernier envoyé.
    Tout ce que tu dois savoir pour vérifier qu'un identifiant est plus récent ou non se trouve dans ce cours. Le code est en C++ mais peut très aisément être traduit en C.
    Ça vérifie qu'ils soit unique, et s'il est plus récent. Ça détaille aussi les pièges lors de la réinitialisation pour cause d'overflow, si ton programme tourne assez longtemps.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  12. #12
    Futur Membre du Club
    sinon je viens d'avoir une idées qui rendrais mon code plus propre, pourquoi pas avoir un thread avec qui l’acquisition qui tourne en permanence et dans mon autre thread je prend quand je le souhaite ma data.
    ça ne serais pas plus simple? avec dans le thread de la réception le contrôle de mon ipoc comme dans le cour pour être sécure

  13. #13
    Expert éminent sénior
    Citation Envoyé par leoleo34 Voir le message
    sinon je viens d'avoir une idées qui rendrais mon code plus propre
    Donc si tu as eu "une" idée alors pas de "s" à "idée". "une" ce n'est pas plusieurs. Et si c'est l'idée qui rendrait le code plus propre et pas toi alors 3° personne du singulier, par 1ère. Ce n'est pas parce que tu fais de l'informatique qu'il faut oublier les règles de grammaire française.

    Citation Envoyé par leoleo34 Voir le message
    ça ne serais pas plus simple? avec dans le thread de la réception le contrôle de mon ipoc comme dans le cour pour être sécure
    Aucune idée, on ne connait pas ton besoin. On ne sait même pas pourquoi tu ne veux traiter que la dernière data. Accessoirement si c'est "ce" qui "serait" plus simple alors là aussi la conjugaison se fait à la 3° personne du singulier.
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  14. #14
    Rédacteur/Modérateur

    T'es conscient que tu travailles avec de l'UDP ? Que la première règle de l'UDP c'est que les envois sont non fiables ? Et la réception potentiellement désordonnée ? Et dupliquée ?
    https://bousk.developpez.com/cours/r...iers-pas/#LIII

    Quand à simplifier en ajoutant un thread.. Je suis perplexe pour ton niveau.
    Tu ajoutes un thread, puis faut ajouter un mutex.
    Puis faut de toute façon que tu changes ta façon de vérifier que le paquet est plus récent ou pas, parce qu'actuellement tout ce que tu vérifies c'est s'il est différent. Et là je te renvois vers la première ligne de ce message et le lien donné.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.