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] Lecture du contenu de la socket


Sujet :

Boost C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut [Boost Asio] Lecture du contenu de la socket
    Bonjour,

    Je suis en train de réaliser un petit tchat avec la librairie Boost asio, du type serveur/client.
    Je me base sur le tuto http://gwenael-dunand.developpez.com...pp/boost/asio/ mais je rajoute une interface graphique avec Qt, et une gestion utilisateur avec base de données.

    Le client se connecte bien au serveur, je reçois le "bienvenue sur le serveur".
    Mais lorsque j'essaye d'envoyer un message du client vers le serveur ( pour envoyer le login) le client plante.
    J'ai repris les fonction d'écriture du serveur et je l'ai transposé au client et vise versa pour les fonction de lecture.

    Es ce que c'est le fait que la socket contient déjà quelque chose ? je dois effacer ce contenu ? ou je dois créé une autre socket entre le client et le serveur pour envoyer un message ?
    Ce n'est pas les messages que je veux envoyer mais juste le login au serveur à la connexion du client.

    Je suis un peu perdu :s

  2. #2
    Expert confirmé
    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
    Points : 4 442
    Points
    4 442
    Par défaut
    Hello,

    On peut voir ton code ? Çà sera plus simple que d'essayer de deviner.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    oui pardon désolé sa sera plus simple


    connexion.cpp,
    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
     
    #include "connexion.h"
     
    connexion::connexion(boost::asio::io_service& io_service) : m_socket(io_service)
    {
        messagerie = new chat;
    }
     
    tcp::socket& connexion::socket()
    {
        return m_socket;
    }
     
    void connexion::read()
    {
         boost::asio::async_read(m_socket, boost::asio::buffer(m_network_buffer),
         boost::asio::transfer_at_least(20),
         boost::bind(&connexion::handle_read, shared_from_this(),
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred));
    }
     
    void connexion::handle_read(const boost::system::error_code& error, size_t number_bytes_read)
    {
        if (!error)
        {
            std::cout.write(&m_network_buffer[0], number_bytes_read);
            read();
        }
        else
        {
            std::cout<<error.message();
        }
    }
     
    // c'est cette procédure que j'aimerais appeler dès que le client se connecte
    void connexion::ecrire()
    {
        std::string m_message;
        m_message = "Message venant du client";
        boost::asio::async_write(m_socket, boost::asio::buffer(m_message), boost::bind(&connexion::handle_write, shared_from_this(), boost::asio::placeholders::error) );
    }
     
    void connexion::handle_write(const boost::system::error_code& error)
        {
            if (!error)
            {
                // Autres actions éventuelles
            }
        }
    client.h
    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
     
    class tcp_client
    {
        public:
                tcp_client(boost::asio::io_service& io_service, tcp::endpoint& endpoint);
     
        private:
            void connect(tcp::endpoint& endpoint)
            {
                connexion::pointer new_connection = connexion::create(m_io_service);
                tcp::socket& socket = new_connection->socket();
                socket.async_connect(endpoint, boost::bind(&tcp_client::handle_connect, this, new_connection, boost::asio::placeholders::error));
            }
     
            void handle_connect(connexion::pointer new_connection, const boost::system::error_code& error)
            {
                if(!error)
                {
                    new_connection->read();
                }
            }
            boost::asio::io_service& m_io_service;
    };
    client.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    tcp_client::tcp_client(boost::asio::io_service& io_service, tcp::endpoint& endpoint) : m_io_service(io_service)
    {
        connect(endpoint);
        std::cout<<"lancement connexion !"<<std::endl;
        //La je ferais appel à connexion::ecrire() mais sa ne marche pas
    }
    server.cpp
    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
     
    tcp_server::tcp_server(boost::asio::io_service& io_service, int port) : m_acceptor(io_service, tcp::endpoint(tcp::v4(), 4000))
    {
        start_accept();
    }
     
    void tcp_server::start_accept()
    {
    	connexion::pointer connexion= connexion::create(m_acceptor.get_io_service());
     
    	m_acceptor.async_accept(new_connection->socket(),
    		boost::bind(&tcp_server::handle_accept, this, new_connection,
    		boost::asio::placeholders::error));
    }
     
    void tcp_server::handle_accept(connexion::pointer new_connection, const boost::system::error_code& error)
    {
    	if (!error)
    	{
    		std::cout << "Reçu un client!" << std::endl;
    		new_connection->start();
    		start_accept();
    	}
    }
    le serveur est sur une vm, je me connecte en local.
    J'ai pas mis le code de la partie graphique, mais si tu veux je peux la rajouter

  4. #4
    Expert confirmé
    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
    Points : 4 442
    Points
    4 442
    Par défaut
    Quelques problèmes de const correctness, mais sinon le problème vient de la fonction connexion::ecrire() :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void connexion::ecrire()
    {
        std::string m_message;
        m_message = "Message venant du client";
        // m_message est une variable locale -> elle sera détruite avant l'envoi du message.
        // il faut une variable avec une durée de vie assez longue : typiquement un membre de ta classe
        // comme m_network_buffer; mais il faut 2 buffers par contre : 1 pour la lecture, 1 pour l'écriture.
        boost::asio::async_write(m_socket, boost::asio::buffer(m_message), boost::bind(&connexion::handle_write, shared_from_this(), boost::asio::placeholders::error) );
    }

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    je viens de créer un buffer dans chaque classe, toujours le même problème.
    J'envoie un std::string, le récupère dans un boost::array différent dans chaque classe

    je te remet le code avec les modifications

    connexion.cpp coté serveur
    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
     
    void tcp_connection::start()
    {
        m_message = "Bienvenue sur le serveur!";
       boost::asio::async_write(m_socket, boost::asio::buffer(m_message),
    			boost::bind(&tcp_connection::handle_write, shared_from_this(),
    			boost::asio::placeholders::error)
    			);
    }
     
    void tcp_connection::handle_write(const boost::system::error_code& error)
    {
        if (!error)
        {
    			// Autres actions éventuelles
        }
    }
     
    void tcp_connection::lire()
    {
       boost::asio::async_read(m_socket, boost::asio::buffer(buffer),
        boost::asio::transfer_at_least(20),
        boost::bind(&tcp_connection::handle_read, shared_from_this(),
        boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred)
    			);
    }
     
    void tcp_connection::handle_read(const boost::system::error_code& error, size_t number_bytes_read)
    	{
    		if (!error)
    		{
    			std::cout.write(&buffer[0], number_bytes_read);
    			lire();
    		}
    		else {
    			std::cout << error.message() ;
    		}
    	}
    connexion.h coté serveur
    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
    class tcp_connection : public boost::enable_shared_from_this<tcp_connection>
    {
    public:
    	typedef boost::shared_ptr<tcp_connection> pointer;
    	static pointer create(boost::asio::io_service& ios)
    	{
    	    return pointer(new tcp_connection(ios));
    	}
    	tcp::socket& socket()
    	{
    		return m_socket;
    	}
    	void start();
        void lire();
    
    
    private:
        boost::array<char, 128> buffer;
        void handle_read(const boost::system::error_code& error, size_t number_bytes_read);
    	tcp_connection(boost::asio::io_service& io_service) : m_socket(io_service)
    	{
    
    	}
    	void handle_write(const boost::system::error_code& error);
    	tcp::socket m_socket;
    	std::string m_message;
    };
    serveur.cpp
    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
    tcp_server::tcp_server(boost::asio::io_service& io_service, int port) : m_acceptor(io_service, tcp::endpoint(tcp::v4(), 4000))
    {
        start_accept();
    }
    
    void tcp_server::start_accept()
    {
    	tcp_connection::pointer new_connection = tcp_connection::create(m_acceptor.get_io_service());
    
    	m_acceptor.async_accept(new_connection->socket(),
    		boost::bind(&tcp_server::handle_accept, this, new_connection,
    		boost::asio::placeholders::error));
    }
    
    void tcp_server::handle_accept(tcp_connection::pointer new_connection, const boost::system::error_code& error)
    {
    	if (!error)
    	{
    		std::cout << "Reçu un client!" << std::endl;
    		new_connection->start();
    		start_accept();
    		new_connection->lire();
    	}
    }
    connexion.h coté 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
    class connexion : public boost::enable_shared_from_this<connexion>
    {
        public:
        connexion(boost::asio::io_service& io_service);
            typedef boost::shared_ptr<connexion>pointer;
            static pointer create(boost::asio::io_service &ios)
            {
                return pointer(new connexion(ios));
            }
            tcp::socket& socket();
            void read();
            boost::array<char, 128> m_network_buffer;
            void ecrire();
    
    private:
         void handle_read(const boost::system::error_code& error, size_t number_bytes_read);
         void handle_write(const boost::system::error_code& error);
         std::string m_message;
         tcp::socket m_socket;
    };
    connexion.cpp coté 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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    connexion::connexion(boost::asio::io_service& io_service) : m_socket(io_service)
    {
    }
     
    tcp::socket& connexion::socket()
    {
        return m_socket;
    }
     
    void connexion::read()
    {
         boost::asio::async_read(m_socket, boost::asio::buffer(m_network_buffer),
         boost::asio::transfer_at_least(20),
         boost::bind(&connexion::handle_read, shared_from_this(),
         boost::asio::placeholders::error,
         boost::asio::placeholders::bytes_transferred));
    }
     
    void connexion::handle_read(const boost::system::error_code& error, size_t number_bytes_read)
    {
        if (!error)
        {
            std::cout.write(&m_network_buffer[0], number_bytes_read);
            read();
        }
        else
        {
            std::cout<<error.message();
        }
    }
     
    void connexion::ecrire()
    {
        m_message = "Message venant du client";
        boost::asio::async_write(m_socket, boost::asio::buffer(m_message), boost::bind(&connexion::handle_write, shared_from_this(), boost::asio::placeholders::error) );
    }
     
    void connexion::handle_write(const boost::system::error_code& error)
        {
            if (!error)
            {
                // Autres actions éventuelles
            }
        }
    client.h
    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
    class tcp_client
    {
        public:
                tcp_client(boost::asio::io_service& io_service, tcp::endpoint& endpoint);
    
        private:
            void connect(tcp::endpoint& endpoint)
            {
                connexion::pointer new_connection = connexion::create(m_io_service);
                tcp::socket& socket = new_connection->socket();
                socket.async_connect(endpoint, boost::bind(&tcp_client::handle_connect, this, new_connection, boost::asio::placeholders::error));
                new_connection->ecrire();
            }
    
            void handle_connect(connexion::pointer new_connection, const boost::system::error_code& error)
            {
                if(!error)
                {
                    new_connection->read();
                }
            }
            boost::asio::io_service& m_io_service;
    };

  6. #6
    Expert confirmé
    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
    Points : 4 442
    Points
    4 442
    Par défaut
    Apparemment tu écris (coté client) avant d'ouvrir la connexion : tu écris dans connect au lieu de handle_connect. La connexion n'est pas encore ouverte à ce moment et donc l'écriture échoue.

    Citation Envoyé par Johnny29 Voir le message
    client.h
    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
     
    class tcp_client
    {
        public:
                tcp_client(boost::asio::io_service& io_service, tcp::endpoint& endpoint);
     
        private:
            void connect(tcp::endpoint& endpoint)
            {
                connexion::pointer new_connection = connexion::create(m_io_service);
                tcp::socket& socket = new_connection->socket();
                socket.async_connect(endpoint, boost::bind(&tcp_client::handle_connect, this, new_connection, boost::asio::placeholders::error));
     
                // écriture avant l'ouverture de la connection ici : new_connection->ecrire(); devrait être dans handle_connect();
                new_connection->ecrire();
            }
     
            void handle_connect(connexion::pointer new_connection, const boost::system::error_code& error)
            {
                if(!error)
                {
                    new_connection->read();
                }
            }
            boost::asio::io_service& m_io_service;
    };

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    Je vient de faire la modification, sa ne change rien.
    Coté serveur, lorsque je commente la ligne de l'appel de la fonction, le client se connecte bien, alors qu'il essaye d'écrire dans le buffer.
    C'est peut être dans le new_connexion->lire() coté serveur, que sa ne va pas ?

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    j'ai bien testé la socket coté client, j'écris bien dessus.
    coté serveur, il ne voit rien.
    Si quelqu'un à 1 idée ?

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    up !
    je n'est toujours pas trouvé, malgré une recherche approfondie

Discussions similaires

  1. Manipulation d'objets socket avec boost::asio
    Par K-you dans le forum Boost
    Réponses: 9
    Dernier message: 14/04/2010, 14h40
  2. boost::asio::ip::tcp::socket est elle thread safe ?
    Par nemodev dans le forum Boost
    Réponses: 4
    Dernier message: 24/02/2010, 13h08
  3. Boost::asio lecture asynchrone
    Par Yanux dans le forum Boost
    Réponses: 2
    Dernier message: 23/04/2009, 11h08
  4. Réponses: 12
    Dernier message: 22/02/2009, 16h31
  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