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

Boost C++ Discussion :

boost asio et serialisation


Sujet :

Boost C++

  1. #1
    Membre éprouvé Avatar de Jérémy Lefevre
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2004
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Luxembourg

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 898
    Points : 969
    Points
    969
    Par défaut boost asio et serialisation
    Bonjour à tous,

    J'ai repris l'exemple simple fourni par le site de boost "daytime" permettant d'envoyer simplement la date et l'heure du jour.
    jusque la tout ce passe très bien le code fonctionne à merveille.

    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
     
    class tcp_connection
        : public boost::enable_shared_from_this<tcp_connection>
    {
    public:
        std::string make_daytime_string()
        {
            using namespace std; // For time_t, time and ctime;
            time_t now = time(0);
            return ctime(&now);
        }
     
        typedef boost::shared_ptr<tcp_connection> pointer;
     
        static pointer create(boost::asio::io_service& io_service)
        {
            return pointer(new tcp_connection(io_service));
        }
     
        tcp::socket& socket()
        {
            return socket_;
        }
     
        void start()
        {
            int i = 0;
            char s[20];
            std::string res = "";
     
     
            while (1) {
                res = itoa(i++, s, 10);
                message_ = make_daytime_string() + res;
     
                boost::asio::async_write(socket_, boost::asio::buffer( message_),
                    boost::bind(&tcp_connection::handle_write, shared_from_this(),
                    boost::asio::placeholders::error,
                    boost::asio::placeholders::bytes_transferred));
                boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
            }
        }
     
    private:
        tcp_connection(boost::asio::io_service& io_service)
            : socket_(io_service)
        {
        }
     
        void handle_write(const boost::system::error_code& /*error*/,
            size_t /*bytes_transferred*/)
        {
        }
     
        tcp::socket socket_;
        std::string message_;
    };
    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
     
    class tcp_server
    {
    public:
        tcp_server(boost::asio::io_service& io_service)
            : acceptor_(io_service, tcp::endpoint(tcp::v4(), 13))
        {
            start_accept();
        }
     
    private:
        void start_accept()
        {
            tcp_connection::pointer new_connection =
                tcp_connection::create(acceptor_.get_io_service());
     
            acceptor_.async_accept(new_connection->socket(),
                boost::bind(&tcp_server::handle_accept, this, new_connection,
                boost::asio::placeholders::error));
        }
     
        void handle_accept(tcp_connection::pointer new_connection,
            const boost::system::error_code& error)
        {
            if (!error)
            {
                new_connection->start();
            }
     
            start_accept();
        }
     
        tcp::acceptor acceptor_;
    };

    et mon client:
    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
    void main(int argc, char *argv[]) {
         if (argc != 3)
                {
                    std::cerr << "Usage: client <host>" << std::endl;
     
                }
     
                boost::asio::io_service io_service;
     
                tcp::resolver resolver(io_service);
                tcp::resolver::query query(argv[2], "daytime");
                tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
     
                tcp::socket socket(io_service);
                boost::asio::connect(socket, endpoint_iterator);
     
                while (1)
                {
                    boost::array<char, 128> buf;
                    boost::system::error_code error;
     
                    size_t len = socket.read_some(boost::asio::buffer(buf), error);
     
                    std::cout.write(buf.data(), len);
                }    
    }

    maintenant j'aimerai passer un object un peu plus complexe qu'une string et c'est la que je bloque.

    je creer une structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            struct message by[sizeof member] =
            {
                { "toto", "tutu" },
            };
    et j'aimerai passer cette structure dans ma socket.

    j'ai donc pensé a la serialiser mais j'ai une contrainte, celle d'etre sous visual studio 2013 qui seemble rencontrer des bugs avec la serialization de boost.

    Known Bugs with Visual Studio 2013/Visual C++ 12

    Visual Studio 2013 was released quite late in the release process, so there exist several unresolved issues. These include:


    • Serialization can't compile because of a missing include.
    • Using has_member_function_callable_with from Boost.Container's allocator_traits causes a compile error (#9332).
    • In libraries such as Unordered and MultiIndex, calling overloaded functions with initializer lists can result in a compile error, with Visual C++ claiming that the overloads are ambiguous. This is a Visual C++ bug and it isn't clear if there's a good workaround. This won't affect code that doesn't use initializer lists, or uses an initializer list that doesn't require an implicit conversion (i.e. an initializer list of the container's exact value type).
    • Thread: ex_scoped_thread compile fails (#9333).

    Donc on y va pour la serialisation à la main et c'est la ou j'ai besoin de vous.

    si je reprend ma classe tcp_connection
    j'y ajoute une fonction de serialisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    size_t serialize(unsigned char *dst, const struct message *object)
        {
            size_t i = 0;
     
            memcpy(&dst[i], &object->id, sizeof object->id);
            i += sizeof object->id;
     
            memcpy(&dst[i], &object->content, sizeof object->content);
            i += sizeof object->content;
     
            return i;
        }
    et la je bloque et ne sait plustrop quoi faire avec ca... donc si vous avez conseils et/ou idées
    merci d'avance
    Rien ne se perd, rien ne se crée, tout se transforme

    ------- -------

  2. #2
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Salut,

    Ne sérialise pas toi même car ce ne sera pas portable (ou alors tu vas devoir t'amuser à gérer l'endianness et la taille des entiers, et je ne parle même pas des flottants...). La technique la plus facile c'est de sérialiser tes données vers un string, tu peux par exemple utiliser boost::lexical_cast<std::string>(data), tu peux préfixer chaque champ par leur taille avant. Ça sera de loin le plus simple pour avoir qql chose de portable ;-)

  3. #3
    Membre éprouvé Avatar de Jérémy Lefevre
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juin 2004
    Messages
    898
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Luxembourg

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

    Informations forums :
    Inscription : Juin 2004
    Messages : 898
    Points : 969
    Points
    969
    Par défaut
    ok j'ai un peu de mal a me visualiser ca! pourrais tu me faire un exemple de serialisation deserialisation avec lexical_cast et ma structure message?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    
    struct message by[sizeof member] =         {             { "toto", "tutu" },         };
    Rien ne se perd, rien ne se crée, tout se transforme

    ------- -------

  4. #4
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    C'est pas une structure C++. D'après ce que je vois ça contient deux strings donc il suffirait de préfixer par leur size, lexical_cast servant principalement à transformer des entiers/flottants en chaine de caractère. Après ça dépendra de ton protocole, c'est toi qui décide ça

Discussions similaires

  1. Boost::Asio et Visual C++ Express 2005
    Par TocTocKiéLà? dans le forum Boost
    Réponses: 11
    Dernier message: 30/12/2007, 21h11
  2. socket ssl & boost::asio
    Par kass28 dans le forum Boost
    Réponses: 0
    Dernier message: 16/10/2007, 09h38
  3. Boost::Asio et code::blocks
    Par TocTocKiéLà? dans le forum Boost
    Réponses: 10
    Dernier message: 10/08/2007, 23h20
  4. Boost::asio et openssl
    Par Floréal dans le forum Bibliothèques
    Réponses: 1
    Dernier message: 18/07/2007, 16h17
  5. Boost::asio : multi threading ou pas?
    Par Alp dans le forum Boost
    Réponses: 9
    Dernier message: 02/09/2006, 22h01

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