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 :

comprendre strand, bind, etc..


Sujet :

Boost C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    août 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : août 2007
    Messages : 125
    Points : 23
    Points
    23
    Par défaut comprendre strand, bind, etc..
    bonjour,

    J'essaie de comprendre les différents tutorial pour avoir un client et un server multithread asynchronique.
    En gros j'aimerai que quand l'un ou l'autre envoie une infos, cela ouvre un thread jusqu'a ce que l'échange soit terminé pendant que d'autre échange(thread) soient donc possible asynchroniquement.

    Donc j'ai chercher sur le net les différents examples... :
    https://www.boost.org/doc/libs/1_77_...cho_server.cpp
    https://www.bogotobogo.com/cplusplus...ronizing_C.php
    https://think-async.com/Asio/boost_a...tuttimer5.html
    (website non sécurisé) https://dens.website/tutorials/cpp-asio/multithreading

    mais franchement je ne comprends pas vraiment la méthode.
    disons qu'avec boost::asio, les classes ou fonctions peuvent avec 1 ou plus arguments, arguments qui peuvent être tel ou tel variable/constante et même en copiant un exemple d'un des tutos pour l'initialisation d'une fonction, je me retrouve quand même avec des erreurs si ce n'est des warnings.


    mon dernier essaie est pour le code coté client, je m'inspire du echo server histoire d'avoir une info à envoyé pour tester si cela fonctionne avec le serveur et du timer pour la methode mais de toutes façon je ne compile pas, bref...

    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
     
    #ifndef MFCHANFLER_H
    #define MFCHANDLER_H
     
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <WinSock2.h>
    #include <boost/asio.hpp>
    #include <boost/thread.hpp>
    #include <boost/bind.hpp>
     
    using namespace std;
    using boost::asio::ip::udp;
     
    class handler
    {
    private:
     
        udp::socket socket_;
        udp::resolver resolver_;
        udp::resolver::results_type endpoints_
            = resolver_.resolve(udp::v4(), "127.0.0.1", "3333");
        udp::endpoint server_endpoint;
        boost::asio::io_context::strand m_strand;
     
    public:
     
        enum { max_length = 1024 };
        char sdata_[max_length];
        char rdata_[max_length];
     
     
        handler(boost::asio::io_service& io)
            :socket_(io), resolver_(io), m_strand(io)
        {
            m_strand.wrap(boost::bind(&handler::send, this));
            m_strand.wrap(boost::bind(&handler::receive, this));
        }
     
        void send()
        {
            cout << "send something" << endl;
            std::cin.getline(sdata_, max_length);
            size_t sdata_length = std::strlen(sdata_);
            socket_.async_send(boost::asio::buffer(sdata_, sdata_length), *endpoints_.begin());
            m_strand.wrap(boost::bind(&handler::send, this));
        }
     
        void receive()
        {
            cout << "receive something" << endl;
            socket_.async_receive(boost::asio::buffer(rdata_, max_length), server_endpoint);
            cout << rdata_ << endl;
            m_strand.wrap(boost::bind(&handler::receive, this));
        }
    };
     
    #endif
    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
     
    int main()
    {
        try
        {        
            boost::asio::io_context io;
            handler h(io);
            boost::thread t(boost::bind(&boost::asio::io_service::run, &io));
            io.run();
            t.join();
        system("pause");
     
        }
        catch (std::exception& e)
        {
            std::cerr << "Exception: " << e.what() << "\n";
        }
     
        return 0;
    }

    Bref, est-ce que quelqu'un peut m'expliquer ou m'orienter vers un autre tutorial peut-être, je suis un peu perdu là.
    merci.


    edit: Je vais essayer de revoir des tutos simplement sur les threads pour adapter une classe thread pour les send et receive de l'exemple echo client/serveur.
    de ce que j'ai compris le strand permet de gerer le coté asynchronique des thread, les organiser, pour qu'ils s'enchaines les uns après les autres mais la méthode avec bind m'échappe.(j'fais pas mal de trucs en même temps, c'est pas évident)

  2. #2
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    5 175
    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 175
    Points : 17 066
    Points
    17 066
    Par défaut
    Bind sert à créer un foncteur: un objet qui dispose d'un operator().

    En gros, ca crée une fonction en préremplissant certains arguments d'une autre fonction.
    Suppose que tu dispose de la fonction int f(int a, int b) { return a + b; }. Alors auto k = bind(f, 1) crée un foncteur dont l'opérateur () est auto operator() (int b) { return f(1, b); }.

    Plus subtilement, une fonction membre dispose d'un premier argument caché, this, qui est l'adresse de l'objet sur lequel la fonction est appelée.
    Par exemple, la, on veut faire executer io.run() il faut donc lier (bind) run à io.
    C'est pour ca que ton client contient: boost::bind(&boost::asio::io_service::run, &io)
    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
    Membre à l'essai
    Profil pro
    Inscrit en
    août 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : août 2007
    Messages : 125
    Points : 23
    Points
    23
    Par défaut
    J'avoue que j'ai un peu du mal avec l'abstraction des données de cette façon mais j'en comprends que le premier argument de bind représentera donc une fonction, et le deuxième argument une variable que l'on veut pour initialiser cette fonction en plus des autres arguments qui seront initialisés dans la classe de la fonction ou son initialisation habituelle.


    j'ai beaucoup de lacune en c++, j'avais une notion de this, j'ai découvert self il n'y a pas longtemps, je connaissais pas vraiment auto... ce n'est pas dérangeant pour utiliser certaines libraries, j'ai déjà ma classe de prête pour la communication avec ma base de données par exemple mais le réseau, quelle plaie...

    Pour l'instant j'ai abandonné le client/server echo, je me suis rendu compte que le chat server se rapprochait le plus de ce que j'avais besoin. J'essaie de le modifier, effacer le header des messages pour le remplacer par mon propre header et le convertir en udp car le programme est avec tcp.
    https://www.boost.org/doc/libs/1_77_..._examples.html

    Je reposterai ici si je n'y arrive pas ou si j'ai d'autres questions.


    Merci.

  4. #4
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 7 084
    Points : 32 766
    Points
    32 766
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par noals Voir le message
    j'ai beaucoup de lacune en c++, j'avais une notion de this, j'ai découvert self il n'y a pas longtemps
    self c'est en Python

    Quant au réseau, tu as des ressources sur ce site-même.
    Et non ce n'est pas forcément simple et on peut difficilement prétendre à des trucs complexes quand on sait à peine utiliser this.

    Après bind, perso je l'ai jamais utilisé, et encore moins depuis les lambda et leur capture. Donc bon je vois pas pourquoi perdre du temps sur ça.
    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
    Membre à l'essai
    Profil pro
    Inscrit en
    août 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : août 2007
    Messages : 125
    Points : 23
    Points
    23
    Par défaut
    L'exemple chat server utilise self, me demande pas pourquoi lol...
    this pour objet et self pour variable de ce que j'ai compris.
    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
     
    void do_write()
        {
            auto self(shared_from_this());
            boost::asio::async_write(socket_,
                boost::asio::buffer(write_msgs_.front().data(),
                    write_msgs_.front().length()),
                [this, self](boost::system::error_code ec, std::size_t /*length*/)
                {
                    if (!ec)
                    {
                        write_msgs_.pop_front();
                        if (!write_msgs_.empty()) //if list is not empty
                        {
                            do_write();
                        }
                    }
                    else
                    {
                        c_handle_.leave(shared_from_this());
                    }
                });
        }
    Merci pour le lien.

    lambda, capture, connais pas non plus, je vois lambda dans du code parfois mais j'ai pas encore lu a ce propos
    https://en.cppreference.com/w/cpp/language/lambda

    Disons que pour le réseau, si je peux avoir mon serveur qui gère chaque clients asynchroniquement et que je comprends bien comment intercepter et gérer les messages transmis, j'ai plus qu'à me faire un switch case: pour les différentes infos que je veux transférer, récupérer de la base de données ou autre.
    Ce sera surement pas codé de la meilleur des façon mais je pourrais avancer avec mon projet.

    Merci

  6. #6
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    5 175
    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 175
    Points : 17 066
    Points
    17 066
    Par défaut
    non, il déclare self comme étant le résultat de share_from_this().
    Et quand on ne comprends du code, on lit la documentation avant de regarder la suite. Par exemple, la, c'est https://en.cppreference.com/w/cpp/me...ared_from_this
    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

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    août 2007
    Messages
    125
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : août 2007
    Messages : 125
    Points : 23
    Points
    23
    Par défaut
    Merci pour ta réponse,
    Il faut que je regarde à propos de "set" aussi mais je reviendrai plus tard, ma fille est née le 12 donc j'suis un peu occupé en ce moment. ^^;

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 26/01/2015, 23h59
  2. Comprendre le Binding en WPF et Silverlight
    Par Nathanael Marchand dans le forum Général Dotnet
    Réponses: 0
    Dernier message: 03/05/2012, 15h50
  3. Comprendre les Binding
    Par Whisperer dans le forum Windows Presentation Foundation
    Réponses: 6
    Dernier message: 25/06/2009, 10h30

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