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 :

Manipulation d'objets socket avec boost::asio


Sujet :

Boost C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut Manipulation d'objets socket avec boost::asio
    Bonjour,

    J'utilise boost::asio pour établir une connexion tcp. Avec un exemple simple (tout dans une classe) pas de problème.

    Mais quand je veux organiser un peu les choses en décomposant mon code en :

    -Une classe qui établit la connexion. (1)
    -Une classe qui gère les échanges sur la socket. (2)
    -etc...

    La manipulation de l'objet Socket me poste un problème. En effet, une fois la connexion établit par ma classe (1), il me faut transmettre l'objet Socket à ma classe (2) pour que celle-ci puisse y lire et y écrire les informations.

    J'ai donc essayé de mettre l'objet Socket en attribut de ma classe (1) et, une fois la connexion établit, passer en paramètre de mon appel à la classe (2) la Socket. Mais j'obtiens des erreurs noncopyable comme suit :

    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
     
     
    Classe(1).c: In constructor ‘Classe(1)::Classe(1)()’:
    Classe(1).c:8: error: no matching function for call to ‘boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_stream_socket()’
    /usr/include/boost/asio/basic_stream_socket.hpp:127: note: candidates are: boost::asio::basic_stream_socket<Protocol, StreamSocketService>::basic_stream_socket(boost::asio::io_service&, const Protocol&, const typename StreamSocketService::native_type&) [with Protocol = boost::asio::ip::tcp, StreamSocketService = boost::asio::stream_socket_service<boost::asio::ip::tcp>]
    /usr/include/boost/asio/basic_stream_socket.hpp:107: note:                 boost::asio::basic_stream_socket<Protocol, StreamSocketService>::basic_stream_socket(boost::asio::io_service&, const typename Protocol::endpoint&) [with Protocol = boost::asio::ip::tcp, StreamSocketService = boost::asio::stream_socket_service<boost::asio::ip::tcp>]
    /usr/include/boost/asio/basic_stream_socket.hpp:86: note:                 boost::asio::basic_stream_socket<Protocol, StreamSocketService>::basic_stream_socket(boost::asio::io_service&, const Protocol&) [with Protocol = boost::asio::ip::tcp, StreamSocketService = boost::asio::stream_socket_service<boost::asio::ip::tcp>]
    /usr/include/boost/asio/basic_stream_socket.hpp:69: note:                 boost::asio::basic_stream_socket<Protocol, StreamSocketService>::basic_stream_socket(boost::asio::io_service&) [with Protocol = boost::asio::ip::tcp, StreamSocketService = boost::asio::stream_socket_service<boost::asio::ip::tcp>]
    /usr/include/boost/asio/basic_stream_socket.hpp:49: note:                 boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_stream_socket(const boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&)
    Classe(1).c: In static member function ‘static void Classe(1)::thread_Connect(Classe(1)*)’:
    Classe(1).c:62: error: no match for call to ‘(boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >) (boost::asio::io_service&)’
    Classe(1).c:69: error: no matching function for call to ‘Classe(2)::lancerEchange(boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >)’
    Classe(2).h:40: note: candidates are: void Classe(2)::lancerEchange(boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >*)
    In file included from /usr/include/boost/asio/basic_socket.hpp:25,
                     from /usr/include/boost/asio/basic_datagram_socket.hpp:26,
                     from /usr/include/boost/asio.hpp:21,
                     from Classe(2).h:10,
                     from Classe(1).h:8,
                     from Classe(1).c:2:
    /usr/include/boost/noncopyable.hpp: In copy constructor ‘boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_io_object(const boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >&)’:
    /usr/include/boost/noncopyable.hpp:27: error: ‘boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)’ is private
    /usr/include/boost/asio/basic_io_object.hpp:30: error: within this context
    In file included from /usr/include/boost/asio/datagram_socket_service.hpp:32,
                     from /usr/include/boost/asio/basic_datagram_socket.hpp:27,
                     from /usr/include/boost/asio.hpp:21,
                     from Classe(2).h:10,
                     from Classe(1).h:8,
                     from Classe(1).c:2:
    /usr/include/boost/noncopyable.hpp: In copy constructor ‘boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp, boost::asio::detail::epoll_reactor<false> >::implementation_type::implementation_type(const boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp, boost::asio::detail::epoll_reactor<false> >::implementation_type&)’:
    /usr/include/boost/noncopyable.hpp:27: error: ‘boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)’ is private
    /usr/include/boost/asio/detail/reactive_socket_service.hpp:58: error: within this context
    In file included from /usr/include/boost/asio/basic_socket.hpp:25,
                     from /usr/include/boost/asio/basic_datagram_socket.hpp:26,
                     from /usr/include/boost/asio.hpp:21,
                     fromClasse(2).h:10,
                     from Classe(1).h:8,
                     from Classe(1).c:2:
    /usr/include/boost/asio/basic_io_object.hpp: In copy constructor ‘boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_io_object(const boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >&)’:
    /usr/include/boost/asio/basic_io_object.hpp:30: note: synthesized method ‘boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp, boost::asio::detail::epoll_reactor<false> >::implementation_type::implementation_type(const boost::asio::detail::reactive_socket_service<boost::asio::ip::tcp, boost::asio::detail::epoll_reactor<false> >::implementation_type&)’ first required here 
    In file included from /usr/include/boost/asio/basic_datagram_socket.hpp:26,
                     from /usr/include/boost/asio.hpp:21,
                     from Classe(2).h:10,
                     from Classe(1).h:8,
                     from Classe(1).c:2:
    /usr/include/boost/asio/basic_socket.hpp: In copy constructor ‘boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_socket(const boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&)’:
    /usr/include/boost/asio/basic_socket.hpp:45: note: synthesized method ‘boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_io_object(const boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp> >&)’ first required here 
    In file included from /usr/include/boost/asio.hpp:29,
                     from Classe(2).h:10,
                     from Classe(1).h:8,
                     from Classe(1).c:2:
    /usr/include/boost/asio/basic_stream_socket.hpp: In copy constructor ‘boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_stream_socket(const boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&)’:
    /usr/include/boost/asio/basic_stream_socket.hpp:49: note: synthesized method ‘boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_socket(const boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&)’ first required here 
    Classe(1).c: In member function ‘boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> > Classe(1)::getSocket()’:
    Classe(1).c:86: note: synthesized method ‘boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >::basic_stream_socket(const boost::asio::basic_stream_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >&)’ first required here 
    make: *** [Classe(1).o] Erreur 1

  2. #2
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Il faut passer la socket en référence...

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut
    J'ai un peu de mal...

    Voilà l'allure de ma classe ConnectionController:

    ConnectionController.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include "Echange.h"
    #include <boost/asio.hpp>
    class ConnectionController {
     
    private:
     
    	Echange echange;
     
    	tcp::socket m_socket;
     
    public :
    	void connectionRequest();
    et pour ConnectionController.c :
    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
     
    void ConnectionController::connectionRequest(){
    	try
    		{
    			boost::asio::io_service ios;
     
    			// On veut se connecter sur la machine locale, port PORT
    			tcp::endpoint endpoint(boost::asio::ip::address::from_string("127.0.0.1"), PORT);
     
    			m_socket(ios);
    			m_socket.connect(endpoint);
     
     
    			echange.lancerEchange(m_socket);
    		}
    		catch (std::exception& e)
    		{
    			std::cerr << "Exception: " << e.what() << "\n";
    		}
    }
    lancerEchange est déclaré comme suit dans Echange.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void lancerEchangeNavtac(boost::asio::ip::tcp::socket &socket);
    Les résultats ne sont pas beaucoup meilleurs et surtout, cette erreur dans la constructeur me semble byzarre (ligne 8 de ConnectionController.c). ça sent l'erreur bête...

  4. #4
    Membre émérite

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Points : 2 252
    Points
    2 252
    Par défaut

    Qu'est-ce que c'est que ce truc ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class ConnectionController {
    private: 
       Classe(2) classe(2);
    //...

  5. #5
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Waaaaaa, j'avais jamais vu ça !
    classe(2) est un nom de classe à proscrire. Le compilo le confond avec un constructeur !!!!

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut
    Lol non je l'ai appelé comme ça pour me faire comprendre. Je n'ai pas du tout ces noms dans mon projet.

  7. #7
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par K-you Voir le message
    Lol non je l'ai appelé comme ça pour me faire comprendre. Je n'ai pas du tout ces noms dans mon projet.
    Ok d'accord. C'est tout de même pas très malin.
    Le mieux reste de donner un exemple minimal, sinon on est obligé de sortir la boule de cristal !

    En ce qui concerne ton erreur, tcp::socket n'est pas copiable. Donc si tu stockes tcp::socket m_socket comme variable membre de ta classe, le seul moyen de l'affecter, c'est dans le constructeur.
    Si tu veux l'affecter pendant l'éxécution, il faudra passer par un pointeur (intelligent de préférence).
    Au passage, tu construis sur la pile un io_service qui sera détruit à la fin de la fin de la fonction connectionRequest, alors que ta socket est en variable membre. Je sais pas trop ce que ça va donner à l'éxécution, disons crash violent ou bien freeze de l'appli. Je pencherai quand même pour le premier !

    Bonne continuation !

    Poukill.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut
    Ok mon nom de classe était innaproprié, mais je ne vois pas comment faire un exemple plus minimal que ça...

    Que représente l'objet io_service ? Faut-il que je le passe en donnée membre également ?

    Parce qu'en Java pour écrire un serveur par exemple on a le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
    ServerSocket s = new ServerSocket(port);
    Socket soc = (java.net.Socket) s.accept();
    Dans ce cas on transmet la socket et puis on ne s'occupe pas du ServeurSocket. C'est juste un objet utilisé pour mettre en place la Socket, mais ensuite, seule la socket assure le maintient de la connexion.

  9. #9
    Membre chevronné
    Avatar de poukill
    Profil pro
    Inscrit en
    Février 2006
    Messages
    2 155
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Points : 2 107
    Points
    2 107
    Par défaut
    Citation Envoyé par K-you Voir le message
    Ok mon nom de classe était inapproprié, mais je ne vois pas comment faire un exemple plus minimal que ça...
    Au temps pour moi, je voulais dire ECM. Exemple complet minimal, c'est à dire un code relativement simple qui compile. L'erreur n'est pas toujours lié au code montré, donc ça permet à d'autres de voir où le bas blesse, et de le compiler soi même si besoin.

    Que représente l'objet io_service ? Faut-il que je le passe en donnée membre également ?
    Cf tutoriel Boost.Asio.
    L'io_service est le coeur de la bibliothèque, c'est là dedans qu'il y a la boucle de gestion des événements. Tu le détruis, plus rien de marche.

    Parce qu'en Java pour écrire un serveur par exemple on a le code :
    [...]
    Dans ce cas on transmet la socket et puis on ne s'occupe pas du ServeurSocket. C'est juste un objet utilisé pour mettre en place la Socket, mais ensuite, seule la socket assure le maintient de la connexion.
    En java, il y a un garbage collector. Donc quand tu fais new, t'as pas besoin de faire delete. En C++, ce n'est pas le cas, s'il y a un new, il y a un delete pas loin. Donc en cas d'allocation sur le tas, la mémoire n'est libérée que si tu le demande. Dans le de l'allocation sur la pile (sans new), c'est détruit quand tu sors de la portée!
    On peut se rapprocher du fonctionnement de java avec les pointeurs intelligents. Ca permet une destruction de l'objet automatique lorsque la ressource est sur le point d'être abandonnée.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    139
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 139
    Points : 48
    Points
    48
    Par défaut
    Il me manquait juste le constructeur qui va bien dans ma classe ConnectionController:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ConnectionController::ConnectionController(boost::asio::io_service& io_service)
      : m_socket(io_service){}
    Ce constructeur permet d'initialiser ma socket membre dès la création de la classe.

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

Discussions similaires

  1. Asynchronisme avec boost::asio
    Par Khan34 dans le forum C++
    Réponses: 4
    Dernier message: 05/10/2013, 15h35
  2. Echange d'objets avec Boost ASIO
    Par CocoLeNain dans le forum Boost
    Réponses: 2
    Dernier message: 08/02/2013, 09h51
  3. Impossible de compiler avec BOOST ASIO
    Par Sentenza31 dans le forum Débuter
    Réponses: 0
    Dernier message: 27/11/2010, 18h52
  4. Envoi de données entières avec boost::asio
    Par K-you dans le forum Boost
    Réponses: 5
    Dernier message: 28/03/2010, 09h07
  5. socket ssl & boost::asio
    Par kass28 dans le forum Boost
    Réponses: 0
    Dernier message: 16/10/2007, 09h38

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