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 :

Envoyer std::map via socket TCP


Sujet :

Langage C++

  1. #1
    Membre actif
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2012
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2012
    Messages : 51
    Par défaut Envoyer std::map via socket TCP
    Bonjour,
    Je voulais envoyer objet std::map via socket tcp, mais toujours j'ai eu un message d'erreur : segmentation fault.
    Est ce que c'est poosible d'envoyer un std::map via socket TCP!!
    merci d'avance

  2. #2
    Membre Expert
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Par défaut
    Bonjour,

    les containers de la STL, std::vector, std::map, std::list ... allouent tous de la mémoire sur le tas, c'est-à-dire que toute l'information de l'objet n'est pas strictement contenu dans l'objet lui-même. Afin de le copier dans un flux (un fichier, une socket, une plage mémoire partagée, ...) il est nécessaire de sérialiser l'objet.

    Plusieurs solutions s'offrent à toi :
    1. utiliser les classes de sérialisation de Boost, par exemple ;
    2. sérialiser toi-même ta map, en envoyant chaque paire contenue séparément dans ta socket TCP et en ajoutant les paires obtenues de l'autre côté dans une map vide ;
    3. écrire un std::allocator pour ta map qui allouera de la mémoire de manière contigüe dans un bloc mémoire que tu maitrises et que tu pourras envoyer bêtement via TCP.


    Bon courage.

  3. #3
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    Juste une petite précision au passage,

    Citation Envoyé par prgasp77 Voir le message
    utiliser les classes de sérialisation de Boost, par exemple ;
    C'est (de loin) la méthode la plus simple.

  4. #4
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Une autre solution peut être d’utiliser une sérialisation format json. Ça a l’avantage de rendre plus facile l’interopérabilité avec d’autres systèmes.

    Je suis toujours circonspect avec la sérialisation boost, car à ma connaissance la stabilité du format binaire n’est pas garantie avec l’évolution en version.

  5. #5
    Membre actif
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2012
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2012
    Messages : 51
    Par défaut
    J'ai choisi d'envoyer( du server) le map pair par pair, <key, data>
    avez vous une idée sur comment regrouper mes donner coté client!!
    en fait l'un de mes donnes c'est une image binaire de taille important
    merci d'avance

  6. #6
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    std::map<int, int> m;
     
    void onReceivePair(std::map<int, int>& m, int key, int value) {
       m.insert(std::make_pair(key, value));
    }
    ?

  7. #7
    Membre actif
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2012
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2012
    Messages : 51
    Par défaut
    Merci mais je pense pas que ca sera possible de seraper les données, car la taille de l'image et trop imprtant
    alos si j'envoi <key0 , image>
    <key1, len>....
    comment je peux savoir le debut et la fin de chaque paire recu

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Salut,

    j'ai l'impression que tu ne sais pas du tout ce que sérialisation signifie en fait ?
    Pour envoyer des data, c'est à toi de choisir le format, et d'écrire la sérialisation et déssérialisation correspondante.
    Si key est une string (nom de fichier ?), tu peux mettre un entier avec la longueur de la chaine, puis la chaine, tout le reste sera le buffer de l'image.
    Ce n'est qu'une idée rapide.
    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.

  9. #9
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    En général, on met un identifiant unique permettant de savoir quelle est la structure, avant la structure elle-même. Cela permet que la lecture ne doive pas absolument savoir dans quelle ordre les données sont supposé arriver, et donc d’être plus robuste aux évolutions et aux corruptions de données.

    Dans ton cas, ça pourrait être quelque chose du genre (je commence la numérotation à 1, pas d’octet 0) :

    octet 1 : 12 --> 12 = identifiant pour « map » (valeur choisie totalement au pif et arbitrairement)
    octet 2 : 10 --> 10 = identiant pour « int » (idem)
    octets 3-6 : valeur du « int »
    octet 7 : 63 --> 63 = identifiant pour « image »
    octets 8-11 : taille de l’image (nombre entier)
    octets 12-X :*données binaires de l’image
    octet X+1 : 10 (identifiant pour int, valeurs suivante)
    octets X+2 - X+5 :*valeur
    ...
    octet Y : 13 --> 13 = terminateur de map

    À la lecture, tu peux facilement reconstruire la structure à partir de ces informations.

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 366
    Par défaut
    Citation Envoyé par prgasp77 Voir le message
    les containers de la STL, std::vector, std::map, std::list ... allouent tous de la mémoire sur le tas, c'est-à-dire que toute l'information de l'objet n'est pas strictement contenu dans l'objet lui-même. Afin de le copier dans un flux (un fichier, une socket, une plage mémoire partagée, ...) il est nécessaire de sérialiser l'objet.
    Bonjour a tous,
    Par rapport a cette remarque, est ce que les conteneurs de POD sont aussi concernés ?
    Il me semble avoir déja croisé des copies de char buffer dans des std::vector<char> par exemple a coup de memcpy.

  11. #11
    Membre Expert
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Par défaut
    Oui. Il est toujours possible d'utiliser memcpy avec des std::vector, mais pas directement sur l'adresse de l'opjet, mais par exemple sur l'adresse retournée par std::vector::data.

  12. #12
    Membre éprouvé
    Inscrit en
    Mai 2012
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2012
    Messages : 65
    Par défaut
    Oui. Il est toujours possible d'utiliser memcpy avec des std::vector, mais pas directement sur l'adresse de l'opjet, mais par exemple sur l'adresse retournée par std::vector::data.
    Dans un contexte où il n'est pas possible d'utiliser du C++11, l'alternative est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    std::vector<T> myVec;
    &myVec[0];

  13. #13
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 766
    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 766
    Par défaut
    Et json + base64


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    {
    {"key": XXX, "data": "data:image/gif;base64,R0lGODlhAQABAAAAACwAAAAAAQABAAA="},
    {"key": XXX, "data": "data:image/jpeg;base64,9j4AAQSkZJRgABAQEAWgBaAAD4gxYSUNDX1BST0ZJTEUAAQEAAAxITGlubwIQAAB"},
    {"key": XXX, "data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA AAAFCAYAAACNbyblAAAAHElEQVQI1"}
    }

    Tes images ne font quand même pas 10, 20, 50 Mo

Discussions similaires

  1. Envoyer un objet via Socket UDP
    Par lastico21000 dans le forum Entrée/Sortie
    Réponses: 0
    Dernier message: 11/02/2012, 14h58
  2. reperer deconnexion lors d'une copie de fichier via socket tcp
    Par dumoulex dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 23/06/2011, 14h57
  3. Envoyer Objet / Structure par socket TCP
    Par crazy33 dans le forum C++
    Réponses: 5
    Dernier message: 21/11/2010, 20h49
  4. Communication via Socket TCP
    Par onet dans le forum Bibliothèques
    Réponses: 28
    Dernier message: 09/10/2009, 16h11
  5. Envoyer des bytes via socket
    Par Mr Chinaski dans le forum Réseau/Web
    Réponses: 2
    Dernier message: 06/11/2008, 18h15

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