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

C++ Discussion :

Envoyer des instances de classes via TCP


Sujet :

C++

  1. #1
    Membre éclairé
    Avatar de ZouBi
    Inscrit en
    Octobre 2007
    Messages
    508
    Détails du profil
    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Octobre 2007
    Messages : 508
    Points : 812
    Points
    812
    Par défaut Envoyer des instances de classes via TCP
    Bonjour,
    voici les deux prototypes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int SDLNet_TCP_Send(TCPsocket sock, void *data, int len);
    int SDLNet_TCP_Recv(TCPsocket sock, void *data, int maxlen);
    Je possède une classe "Personnage", dont j'en fais une instance, et que je souhaite envoyer au serveur.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Personnage p();
    SDLNet_TCP_Send( sock, &p, sizeof( Personnage );
    Jusqu'ici, aucun soucis, mais c'est lors de la réception au serveur, du personnage que celui-ci me fait une erreur de segmentation.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Personnage p();
    SDLNet_TCP_Recv( sock, &p, sizeof( Personnage );
    voilà, et là une erreur de segmentation.
    La classe Personnage possède un constructeur par copie, ainsi qu'une surcharge de l'opérateur d'affectation.

    Je pensais au début qu'on pouvait pas envoyer d'instance via TCP, mais j'ai pourtant essayer avec des entiers ( en remplacant les types Personnage par des int ) et j'ai toujours des erreurs de segmentation, donc je sais pas comment faire, si vous pouvez m'aider.

  2. #2
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 896
    Points : 1 912
    Points
    1 912
    Par défaut
    On me détrompera peut-être, mais il me semble qu'au lieu d'envoyer une classe sur le réseau, on envoie plutôt ses données. Essaie plutôt de faire une méthode dans ta classe (std::string Personnage::ToMessage()) qui renvoie une chaîne de caractère contenant les données de ta classe de manière formatée (des mots ou chiffres séparés par des ';', par exemple, à toi de voir ce qui est nécessaire pour instancier un Personnage), et à l'autre bout fait une fonction (ou une méthode de classe) qui permet d'analyser la chaîne reçue, d'en extraire les données nécessaires, et de construire un Personnage à partir de ça.

  3. #3
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Ton problème s'appelle la serialisation ou aussi le marshalling.

    Comment transmettre une classe ou des données d'un PC à l'autre sachant qu'ils ne partagent pas de mémoire commune. Vu que la mémoire n'est pas partagée, un pointeur ne se transmet pas, il faut absolument le déréférencer et sérialiser.

    Vu que tu es dans un forum c++, je peux continuer sur les autres classes standard, comment transmettre un vector

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    send(socket, &vector, sizeof(vector));
    et à l'autre bout
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    recv(socket, &vector, sizeof(vector));
    C'est le crash assuré.

    Il va donc falloir que tu parcours chacuns des membres de ta classe, que tu les envoies sur le socket et qu'à l'autre bout, tu les recoives et reconstruises ta classe de toute pièce.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  4. #4
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    ram_0000 a raison... Et c'est pourquoi je te conseille de lire la sérialisation avec Boost. Ensuite, tu as donc à sérialiser, envoyer la chaine à l'autre ordi, et dé-sérialiser.

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Et accessoirement, ton autre problème c'est que ceci déclare une fonction :
    Ceci par contre déclare bien une instance de Personnage :

  6. #6
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Citation Envoyé par Laurent Gomila Voir le message
    Et accessoirement, ton autre problème c'est que ceci déclare une fonction :
    Heu non, ceci déclare bien une instance de Personnage nommée "p" et dont ont ne passe aucun paramètre au constructeur. C'est strictement equivalent à

    mais peut être moins facile à lire (quoique)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    Et non, c'est un piège.

    Est bien une déclaration de fonction. A comparer avec :

    Quand il y a ambiguïté, le compilateur doit préférer la déclaration de fonction. Il y a des cas encore pires...


    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
    struct A
    {
    	A() {}
    };
     
    struct B
    {
    	B(A a1, A a2) {}
    	void f() {}
    };
     
    int main()
    {
    	int i = 12;
    	B b1 (A(i), A());  // déclare une fonction b1
    	B b2 (A(12), A()); // déclare une variable b2
    }
    b1 est une fonction prenant deux paramètres, et retournant un objet de type B.
    Le premier paramètre, nommé i (avec des parenthèses en trop, mais c'est pas grave), de type A.
    Le second paramètre, non nommé de type : pointeur sur une fonction ne prenant pas d'argument et retournant un A.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    Oups, j'aurai dit une grosse connerie !!! Et aussitôt, je pris mon compilateur...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    class A
    {
    public:
       A(int param = 12)
       {
          printf("A constructor(%d)\n", param);
       }
    };
    Avec ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void main()
    {
       A tst();
    }
    J'ai ce warning : warning C4930: 'A tst(void)'*: fonction prototypée non appelée (était-ce la définition de variable souhaitée*?)

    Avec ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void main()
    {
       A tst(10);
    }
    Pas de warning et j'ai le comportement souhaité.

    Avec ce code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void main()
    {
       A *tst = new A();
    }
    Pas de warning non plus et j'ai le comportement souhaité.

    Donc mes excuses Laurent Gomila, tu avais raison et merci JolyLoic d'avoir rectifié mon erreur, j'aurai au moins appris une chose aujourd'hui.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  9. #9
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    Pourquoi utilises tu des pointeurs et des new alors qu'il n'y en a absolument pas besoin, et qu'au contraire ça apporte rien que des problèmes ?
    Boost ftw

Discussions similaires

  1. Instance de classe via DLL
    Par Fire Angel dans le forum Langage
    Réponses: 4
    Dernier message: 31/08/2009, 16h44
  2. Créer des instances de classes EMF dans Eclipse avec une jolie IHM
    Par obernard dans le forum Eclipse Platform
    Réponses: 3
    Dernier message: 24/02/2009, 19h21
  3. Réponses: 4
    Dernier message: 28/03/2007, 22h23
  4. Réponses: 6
    Dernier message: 23/02/2006, 20h23
  5. Conditions de destruction des instances de classes
    Par elvivo dans le forum Général Python
    Réponses: 4
    Dernier message: 29/12/2004, 17h16

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