IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

Langage C++ Discussion :

Appel de fonction fille depuis une classe mère


Sujet :

Langage C++

  1. #1
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 465
    Points
    465
    Par défaut Appel de fonction fille depuis une classe mère
    Bonjour,

    Je me retrouve dans une impasse suite à la recherche d'un moyen d’empêcher un comportement ennuyant des listes d'objets (je n'ai rien trouvé de concluant sur google mais mes termes de recherches sont peu être incorrect)

    Mon problème est plutôt simple en soit:
    Je crée une liste d'objet IP_PACKET (ma classe mère) cependant ceux ci sont en vérité des objets de classe fille de IP_PACKET qui remplace (override) la méthode getContent() de IP_PACKET
    ce qui se passe dans le code ci-dessous est qu'uniquement la méthode getContent de IP_PACKET est appelé et non celle d'une des classes filles.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        stream=(char*) malloc(packets.size()*BUFFERSIZE);
        list<IP_PACKET>::iterator i;
        printf("packing all data!\n");
        for(i=packets.begin();i!=packets.end();++i)
        {
            printf("'%s'",(*i).getContent());
            strcat(stream,(*i).getContent());
        }
    Ma question est du coup est il possible d'appeler ma méthode getContent en utilisant ma list de IP_PACKET tout en utilisant uniquement les méthodes des classes filles, ou est ce qu'il faut obligatoirement que je teste mon objet pour obtenir son type et le re-caster dans son type original puis appelé sa méthode getContent?

    Merci d'avance

    P.S je me suis peut être trompé de section ne sachant pas si ma question allait dans les généralité du langage ou plus dans la STL

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    en fait, une list de n'importe quoi contient précisément des valeurs de ce type-là.
    Ces valeurs sont initialisés en appelant un des constructeurs (constructeur de copie pour push_back, un constructeur compatible dans le cas de emplace_back).

    Ainsi, une list<IP_PACKET> contient des IP_PACKET, pas des classes de bases.
    Quand tu appelles liste.push_back(dérivée);, un IP_PACKET est ajouté à liste, sa valeur est celle la même que si tu créais la variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IP_PACKET copie(dérivée);
    .

    C'est le phénomène de slicing.

    Pour avoir une liste d'objets dérivés, il faut une liste d'objets dérivés, ou éventuellement une liste de pointeurs vers des objets de base (mais auquels cas, tu peux avoir d'autres types que ton type dérivé).

    Un cast vers une classe dérivée signifie pratiquement toujours que tu as perdu trop tot une information.
    La faute est généralement celle de la fonction qui retourne la liste.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    En fait, pour que cela puisse fonctionner, il faudrait utiliser la méthode dite du "retour covariant", ce qui revient, en gros, à faire varier le type de retour de la fonction sur base du type réel de la donnée de base. Mais, comme la technique est particulièrement lourde et que, de plus, cela ne ferait que retarder le problème (il faudra bien, à un moment ou à un autre, s'intéresser au type réel de la donnée renvoyée par ta fonction), je peux t'assurer que ce n'est surement pas ce que tu veux faire.

    Par chance, David Wheeler nous a dit il y a déjà bien longtemps :
    Citation Envoyé par David Wheeler
    All problems in computer science can be solved by another level of indirection

    (tous les problèmes en sicence informatique peuvent être résolus par un niveau d'indirection supplémentaire)
    Et c'est le principe que je te conseillerais de mettre à l'oeuvre.

    En effet, le simple fait de vouloir avoir recours à une fonction getContent() démontre que tu t'intéresse bien d'avantage aux données que tu manipules qu'à la manière dont tu veux les manipuler, et ca, c'est pas vraiment la meilleure chose que tu puisses envisager de faire.

    L'idée générale serait donc d'utiliser ce que l'on appelle le "double dispatch" et de créer "quelque chose" qui pourrait manipuler les différents types réels dérivés de ta classe de base, et, de cette manière, définir un comportement spécifique pour chaque contenu possible.

    Un exemple (parmi d'autres) de cette technique correspond à un patron de conception identifié par le GoF sous le nom de visiteur. Mais d'autres solutions pourraient être envisagées
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 465
    Points
    465
    Par défaut
    Re-Bonjour,

    Merci de vos réponse rapide, qui m'ont permis d'apprendre deux trois truc (une list copie des objet et n'utilise pas un pointeur sur le vrai objet ...)
    du coup je pense qu'il s'agit plus de ma manière de stocker mes objet qui est incorrect:
    à la base je voulais faire quelle que chose s'approchant (en JAVA) d'une liste d'interface me permettant de me passer du type de l'objet.

    Je vais vous expliquer ce que je souhaitais faire à la base (peut-être pourrez vous me conseillez sur de meilleur choix ^^)
    le programme est un sniffer de réseau qui crée des objets qui dérivent de l'interface (je ne sais pas si c'est vraiment ça en c++, il s'agit d'une classe contenant uniquement des méthode virtuelle ) PACKET
    une arbre d’héritage des classes serait
    PACKET-> ETHERNET_PACKET -> IP_PACKET -> TCP_PACKET
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class PACKET
    {
        public:
            virtual char * ToStr()=0;
            virtual char * getContent()=0;
        protected:
     
        private:
    };
    La classe packetFactory va crée mes objets et me retourner un PACKET * qui peut être un TCP_PACKET, UDP_PACKET etc ...

    et j'en suis la ...

    le but du bout de code que je vous ai soumis était de me permettre de reconstitué un flux sans les headers (que ce soit TCP ou UDP ou ETC tant qu'il s'agit d'un fils de PACKET) et comme expliqué plus tôt c'est la que ça bloque

    Du coup j'ai regardé le lien sur le problème des visiteurs mais je n'est pas très bien compris comment l'appliquer à mon problème
    Si j'ai bien compris il faudrait que je rajoute dans IP_PACKET une méthode de traitement de toutes ces classes filles (ce qui risque d’être très lourd vu le nombre de protocole utilisant IP) ?

    @Koala01 tu dis
    L'idée générale serait donc d'utiliser ce que l'on appelle le "double dispatch" et de créer "quelque chose" qui pourrait manipuler les différents types réels dérivés de ta classe de base, et, de cette manière, définir un comportement spécifique pour chaque contenu possible.
    ce que tu me dis m'as l'air de contredire ce que je croit avoir compris ... il faudrait en quelque sorte que je crée une sorte de PacketProcessor qui prendrait un packet en argument et qui fait quoi?
    1 me retourne la classe correcte pour le paquet.
    2 effectue le traitement du paquet ... (je vois pas trop comment mais on sais jamais)
    3 me retourne le paquet casté dans ça bonne classe

    @leternel tout d'abord merci de m'aider une fois de plus ^^ (tu dois pas te souvenir de moi mais de mon coté je me souviens que tu m'avais déjà aidé )
    Ce que tu me conseille de faire c'est d'utiliser une liste de classe par paquet?
    en occurrence une liste de TCP , une de UDP et ainsi de suite pour tous les paquets ?
    ou éventuellement une liste de pointeurs vers des objets de base
    ce qui voudrait dire que je pourrais faire ca?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    TCP_PACKET tcp=new TCP_PACKET();
    UDP_PACKET udp=new UDP_PACKET();
    list<PACKET *> li;
    list<PACKET *>::iterator i;
    li.push_back(&tcp);
    li.push_back(&udp);
    for(i=li.begin();i!=li.end();++i)
        {
         i->getContent();
        }
    Merci beaucoup.

    P.S excusez moi d'avance pour les char * à la place des strings je viens du C à la base
    EDIT vu qu'il s'agit de pointeur c'est la flèche et non le point

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Tagashy Voir le message
    La classe packetFactory va crée mes objets et me retourner un PACKET * qui peut être un TCP_PACKET, UDP_PACKET etc ...

    et j'en suis la ...
    Bon, à ce stade, tu dois te dire que tu ne veux surtout pas mélanger tes paquets TCP avec des paquets UDP...

    Tu peux donc envisager d'avoir recours à une fabrique qui te créera le bon type de paquets (c'est toujours plus facile par la suite ) mais tu ne devras jamais avoir une liste de "paquets ip" sans précision particulière : ce sera soit une liste de paquets TCP, soit une liste de paquets UDP, JAMAIS une liste pouvant contenir les deux

    solution possible, étant donné que la gestion de la liste proprement dite restera la même, que tu décides de travailler avec des paquets UPD ou avec des paquets TCP est donc de mettre en place un moyen "simple" de choisir la "politique de traitement" associée à chaque liste : tu aurais donc une politique particulière, adaptée au traitement des paquets UDP et une autre, adaptée au traitement des paquets TCP et tu t'arrangerais (d'une manière ou d'une autre) pour que la politique choisie dépende... du type de paquets que tu placerais dans la liste de paquets
    le but du bout de code que je vous ai soumis était de me permettre de reconstitué un flux sans les headers (que ce soit TCP ou UDP ou ETC tant qu'il s'agit d'un fils de PACKET) et comme expliqué plus tôt c'est la que ça bloque
    Comme je l'ai indiqué plus haut, l'idéal est de fournir "quelque chose" (je viens d'utiliser le terme de politique de traitement) qui puisse prendre en charge le traitement d'un type de particulier de paquets et qui serait utilisée en fonction du type particulier de paquets que tu déciderais de mettre dans la liste

    Etant donné que, a priori, tu connaîtra le type des paquets que tu envisage de placer dans la liste en question au moment de la compilation, je me dis que l'approche "purement oo" montre sans doute ses limites, vu qu'elle reporte le fait de déterminer le type réel de tes paquets à la période du "run time" et donc qu'une approche générique (comprends : basée sur les template, les traits et les politiques) serait sans doute bien plus adaptée
    Du coup j'ai regardé le lien sur le problème des visiteurs mais je n'est pas très bien compris comment l'appliquer à mon problème
    Si j'ai bien compris il faudrait que je rajoute dans IP_PACKET une méthode de traitement de toutes ces classes filles (ce qui risque d’être très lourd vu le nombre de protocole utilisant IP) ?
    Pourquoi pas un simple bool accept(PacketProcessor /* const */ & ) const; qui serait déclarée comme étant une fonction virtuelle pure dans ta classe de base et redéfinie sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bool TcpPaquet:: accept(PacketProcessor /* const */ & pp) const{
        return pp.process(*this);
    }
    dans les classes dérivées

    où PacketProcessor serait une classe de base susceptible de "traiter" les différents types de paquets, et, idéalement, que tu pourrais faire dériver afin d'effectuer plusieurs traitements différents sur chaque type de paquets
    @Koala01 tu dis
    ce que tu me dis m'as l'air de contredire ce que je croit avoir compris ... il faudrait en quelque sorte que je crée une sorte de PacketProcessor qui prendrait un packet en argument et qui fait quoi?
    1 me retourne la classe correcte pour le paquet.
    2 effectue le traitement du paquet ... (je vois pas trop comment mais on sais jamais)
    3 me retourne le paquet casté dans ça bonne classe
    C'est la solution numéro 2 qu'il faudrait choisir : La fonction accept dont je viens de parler part du principe que chaque instance particulière de ta notion de paquet (sans précision) sait exactement de quel type elle est en réalité.

    En faisant en sorte que la fonction process() de ton PacketProcessor prenne spécifiquement un paramètre du type réel de ton paquet (TcpPacket OU UdpPacket OU ....), tu aurais la certitude que chaque "surcharge" de cette fonction ne puisse travailler qu'avec des éléments d'un types bien particulier, clairement connu comme tel à l'exécution, au départ desquels tu as même -- confort suprême, en tant que développeur -- l'occasion d'invoquer toutes les fonctions membres spécifiques au type bien particulier de paquets que tu traites.

    Cependant, je crois sincèrement que, les choses étant ce qu'elles sont (en gros : qu'on ne voudra JAMAIS mélanger les paquets TCP avec les paquets UDP), je crois sincèrement que tu trouverais pas mal d'avantages à adopter une approche générique
    @leternel tout d'abord merci de m'aider une fois de plus ^^ (tu dois pas te souvenir de moi mais de mon coté je me souviens que tu m'avais déjà aidé )
    Ce que tu me conseille de faire c'est d'utiliser une liste de classe par paquet?
    en occurrence une liste de TCP , une de UDP et ainsi de suite pour tous les paquets ?

    ce qui voudrait dire que je pourrais faire ca?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    TCP_PACKET tcp=new TCP_PACKET();
    UDP_PACKET udp=new UDP_PACKET();
    list<PACKET *> li;
    list<PACKET *>::iterator i;
    li.push_back(&tcp);
    li.push_back(&udp);
    for(i=li.begin();i!=li.end();++i)
        {
         i->getContent();
        }
    Crois moi, s'agissant de paquet ip, tu ne veux surtout pas pouvoir faire ce genre de monstruosités : tu peux vouloir traiter des listes de paquets UDP et des listes de paquets TCP, mais tu ne tiens absolument pas à mélanger tes torchons et tes serpillières (même si une grosse partie de mon intervention a, effectivement, pour but de te permettre ce genre de choses)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 465
    Points
    465
    Par défaut
    bonjour,

    Merci pour ta réponse koala01

    J'ai mis en place un github pour permettre de lire le code plus facilement vu qu'il y as beaucoup de fichier, accessible via ce lien
    Il y as la dernière version du code source.

    tu me dis
    Tu peux donc envisager d'avoir recours à une fabrique qui te créera le bon type de paquets (c'est toujours plus facile par la suite )
    il me semble que justement ma classe PacketProcessor en est justement une (ou je me trompe peut être sur le principe d'une factory) vu qu'elle va déterminer quel type de paquet est mon paquet et me renvoyer un objet qui hérite de PACKET ma classe abstraite dont hérite tout mes paquets.

    mais du coup si j'ai bien compris ce que tu me dis en gros il faudrait que je récupère le paquet retourné par PacketProcessor, lui demander son type et l'ajouter à la bonne liste?
    si je reprend mon main
    (les ajout sont en rouge)
    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
    IP_DIALOG udp=IP_DIALOG();
    IP_DIALOG tcp=IP_DIALOG();
    IP_DIALOG it=IP_DIALOG();
            PacketProcessor * pk= new PacketProcessor();
            RAW_SOCKET * rw=new RAW_SOCKET();
            void * buffer=malloc(BUFFERSIZE);
            int x=0,i=0,j=0;
            for(i=0;i<200;i++)
            {
                x=rw->read(buffer,BUFFERSIZE);
                PACKET * packet=pk->ProcessPacket(buffer,x);
                if(packet!=NULL)
                {
                    printf("adding packet!\n");
                        if(packet.getProto()=="tcp")
                              tcp.addPacket(dynamic_cast<TCP_PACKET*>(packet);
                        else if(packet.getProto()=="udp")
                              udp.addPacket(dynamic_cast<UDP_PACKET*>(packet);
                    it.addPacket(dynamic_cast<IP_PACKET*>(packet));
                }
    en gros c'est comme ça qu'il faudrait que je procède? en ajoutant un surcharge sur le type de variable passe a addPacket pour effectuer un traitement spécifique?

    qu'entend tu par template à ce niveau là?
    Etant donné que, a priori, tu connaîtra le type des paquets que tu envisage de placer dans la liste en question au moment de la compilation, je me dis que l'approche "purement oo" montre sans doute ses limites, vu qu'elle reporte le fait de déterminer le type réel de tes paquets à la période du "run time" et donc qu'une approche générique (comprends : basée sur les template, les traits et les politiques) serait sans doute bien plus adaptée
    il est possible que ceci m'aide mais je n'en ais jamais fait et je ne comprend pas vraiment ce que c'est donc j'ai du mal a voir ce que tu veux me dire ;(


    En faisant en sorte que la fonction process() de ton PacketProcessor prenne spécifiquement un paramètre du type réel de ton paquet (TcpPacket OU UdpPacket OU ....), tu aurais la certitude que chaque "surcharge" de cette fonction ne puisse travailler qu'avec des éléments d'un types bien particulier, clairement connu comme tel à l'exécution, au départ desquels tu as même -- confort suprême, en tant que développeur -- l'occasion d'invoquer toutes les fonctions membres spécifiques au type bien particulier de paquets que tu traites.
    le problème c'est que justement le but de la fonction process est de déterminer de quel type est mon paquet vu que je ne lui donne juste le contenue de recvfrom du socket raw...
    actuellement il n'y as pas de traitement sur les paquets juste une catégorisation le seul 'traitement' serait avec IP_DIALOG qui tente de reconstitué le flux de paquet en recuperant le contenue de sa liste de paquet (enfin la liste est pas adapté mais dans le principe)

  7. #7
    Membre régulier
    Homme Profil pro
    Développeur .NET/C/C++
    Inscrit en
    Septembre 2007
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur .NET/C/C++
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Septembre 2007
    Messages : 71
    Points : 122
    Points
    122
    Par défaut
    Salut!

    voilà, je viens de jeter un coup d'oeil à ton code. Le problème de base est simple:
    Dans la classe dialog, tu stocke des objets de type IP_PACKET. Du coup cette liste ne contient que des objets de type IP_PACKET.
    Si tu veux pouvoir mettre des objets de type TCP_PACKET ou UDP_PACKET, le plus simple est de stocker non pas le paquet en lui-même mais un pointeur vers celui-ci.
    Concrètement, il te suffit de remplacer dans IP_DIALOG.h
    par
    et dans IP_DIALOG.cpp
    par
    et (à priori) ça devrait le faire .

    La raison?
    En fait, quand tu déclares ta liste en tant que list<IP_PACKET>, celle-ci contient des IP_PACKET et seulement des IP_PACKET (pas de TCP_PACKET ou UDP_PACKET) copiés sur base de la partie correspondante des variables passées en paramètre du push_back (et donc oui, seulement une partie du paquet est copiée!).
    Du coup, comme chaque élément est un IP_PACKET, ton compilo va appelé la version de la méthode getContent(); qui appartient à la classe IP_PACKET.

    Maintenant, en stokant dans ta liste des pointeurs tu évites le phénomène de copie partielle. On ne fait en effet plus de copie que d'un pointeur vers le paquet et non du paquet lui-même. Ensuite, au moment de l'appel à it->getContent(), le programme va au moment de dérérérencer le pointeur récupérer le type de la valeur pointée, donc du paquet de départ qui sera soit TCP_PACKET soit UDP_PACKET, et appeler la surcharge de getContent() correspondante. Et le tour est joué

    Voilà, J'espère avoir été clair dans mes explications.
    Bonne soirée!
    "Toujours en faire plus pour en faire moins"

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    J'arrive comme un cheveu sur la soupe ... mais ton truc me semble capillotracté

    Et pourquoi pas un truc comme cela?

    Tu exposes un type de paquet (à voire si tu le mets à l'intérieur de ta classe PacketProcessor):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef enum e_PACKET_TYPE /*: unsigned char*/ {
        TYPE_UDP = 0,
        TYPE_TCP
    } PACKET_TYPE;
    Et ensuite, tu fais un truc comme cela:

    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    class Packet_Management {
    public:
     
        Packet_Management() { clear(); }
     
     
        void add_packet(PACKET_TYPE type) {
            switch(type) {
            case TYPE_UDP:
    //          À tester s'il faut un push_back ou un resize
                break;
     
            case TYPE_TCP:
    //          À tester s'il faut un push_back ou un resize
                break;
            }
        }
     
     
        void clear() {
            list_TCP.clear();
            list_UDP.clear();
        }
     
     
    //  À voir si tu as besoin de manipuler le contenu ou bien laisser faire la classe
    //  faire le traitement
     
    //  À voir si on passe directement le pointeur du buffer contenu dans le paquet
    //  ou si on fait une recopie (*)
     
    //  index: 0 based index
        bool get_content(char* content, PACKET_TYPE type, unsigned short index) {
            bool ret;
     
     
            switch(type) {
            case TYPE_UDP:
                if (list_UDP.size() >= index) {
    //              *
                    ret = true;
                } else {
                    ret = false;
                }
                break;
     
            case TYPE_TCP:
                if (list_TCP.size() >= index) {
    //              *
                    ret = true;
                } else {
                    ret = false;
                }
                break;
     
            default:
                ret = false;
               break;
            }
     
            return ret;
        }
     
    private:
     
        vector<ETHERNET_PACKET> list_TCP;  
     
        vector<ICMP_PACKET> list_UDP;  
    };

  9. #9
    Membre confirmé
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Mars 2014
    Messages
    158
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur sécurité

    Informations forums :
    Inscription : Mars 2014
    Messages : 158
    Points : 465
    Points
    465
    Par défaut
    bonjour,
    Merci de vos reponse

    je n'ai pas eu le temps de mettre a jour le github mais je suis effectivement partis sur la solution de Bountykiller cependant cela m'a poser un probleme de concept de mes paquet en effet je réecris le même buffer pour chaque paquet ce qui fait que je n'ai que le dernier de correct
    Je suppose donc qu'il faut que je copie le paquet en l'inserant dans ipdialog ce qui ne marche pas avec un pointeur ^^ je suis actuelement en recherche de solution

    Foetus
    J'ai lue ton code et j'ai compris qu'il s'agisais d'un traitement specifique en fonction des type de l'enumeration mais je suis perdu sur le fonctionement (je debute en c++) du coup peux tu m'expliquer plus precisement ton code, ou me referer a des docs

    P.S je vais bientot mettre a jour le github

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Tagashy Voir le message
    Je suppose donc qu'il faut que je copie le paquet en l'inserant dans ipdialog ce qui ne marche pas avec un pointeur ^^ je suis actuelement en recherche de solution
    Pourquoi cela ne fonctionnera pas? Il faut faire une copie de paquet: recopie des attributs et un memcpy pour recopier le buffer.


    Citation Envoyé par Tagashy Voir le message
    Foetus ... peux tu m'expliquer plus precisement ton code, ou me referer a des docs
    Je ne sais pas exactement ce que tu veux faire

    En gros actuellement tu as (si je ne me trompe pas): une usine pour créer 2 types de paquets, 2 listes plus ou moins globales une pour chaque type de paquets.
    Et ta logique est partagée un peu partout: la création dans l'usine, les spécificités dans chaque classe, le stockage avec des listes et la manipulation est externe (puisque tu as codé un getContent)

    Moi je propose une seule classe Packet_Manager Packet_Holder avec un enum pour chaque type de paquets

    Et cette classe:
    1. va stocker les paquets. On peut faire autrement, mais tu mets en attributs 2 listes.
    2. va permettre d'ajouter des paquets Packet_Holder::add(type)
    3. va manipuler les paquets et éviter de récupérer le contenu (à moins que tu en aies besoin): Packet_Holder::copy(paquet, type) Packet_Holder::search(paquet, type), ...
    4. S'occuper à envoyer/ recevoir les paquets au lieu de mettre le code dans chaque paquet.


    Étant donné que c'est du réseau, il y a juste à formater un buffer pour créer un paquet: tu n'as pas forcément besoin d'un type spécifique pour cela.
    Donc tu peux mettre le code spécifique dans le Packet_Holder::add(type).
    Après si tu as d'autres besoins, faire 2 types peut être utile.

    Enfin il faut attention: si la classe Packet_Holder devient trop grosse, il faudra la casser en plusieurs morceaux: soit faire 2 Packet_Holder, soit 1 Packet_Holder + 2 "contrôleurs" TCP/ UDP, soit faire comme tu es en train de faire usine/ stockage/ "contrôleurs"


    Édit: koala01 et les managers: je l'avais déjà titillé à ce sujet sur un autre fil

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par foetus Voir le message
    Moi je propose une seule classe Packet_Manager avec un enum pour chaque type de paquets
    Hummm... ton idée est bonne, mais je suis relativement allergique aux termes manager, gestionnaires et autres termes semblables

    Vu ce que tu propose que puisse faire ta classe, j'utiliserais plus volontiers le terme holder au terme manager, pour une raison toute bête : le terme holder définit une responsabilité précise qui est de maintenir les (paquets ip) données en mémoire, afin d'y donner accès d'une manière ou d'une autre.

    Le terme "manager", quant à lui se traduit par "gestionnaire", et regroupe tout ce qui peut entrer dans le cadre de "la gestion des données". Ce genre de responsabilité est beaucoup plus large, car il regroupe (par exemple) le fait de créer ou de modifier les (paquets ip) données, ce qui risque, à termes, de t'inciter à rajouter tant et plus de services qui pourraient être considérés comme "entrant dans la gestion" des (paquets ip) données.

    Si bien qu'il y a neuf chances sur dix pour que, à termes, un "data_manager" finisse par regrouper un nombre particulièrement de concepts "plus précis" reliés à la "gestion des données" qui auraient dû être représentés par des concepts (classes) clairement distinctes, et qui introduira de facto un couplage très fort entre ce gestionnaire et "le reste de ton application".

    Je le redis, l'idée de disposer d'un moyen permettant de maintenir les données à un endroit particulier est des plus intéressantes. Je voudrais juste que l'on évite le terme de "gestionnaire" comme la peste quand il s'agit de définir un tel concept
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Appele d'une fonction extérieure depuis une classe
    Par Slayes dans le forum Objective-C
    Réponses: 2
    Dernier message: 07/05/2014, 21h04
  2. appel d'un ejb depuis une classe simple sur jonas
    Par mraniy dans le forum JOnAS
    Réponses: 2
    Dernier message: 16/01/2010, 02h48
  3. Instanciation d'une classe fille depuis une classe mère
    Par khaled-benloucif dans le forum Langage
    Réponses: 2
    Dernier message: 30/01/2009, 23h59
  4. Accèder à une classe fille depuis la classe mère
    Par Phreak0x dans le forum Windows Forms
    Réponses: 3
    Dernier message: 28/10/2008, 10h14
  5. [VBA-E] Appel de fonction/procédure depuis une variable
    Par truman dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 09/05/2006, 16h20

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo