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 :

Asio : Obligé de se reconnecter avant chaque requête ?


Sujet :

Boost C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 142
    Par défaut Asio : Obligé de se reconnecter avant chaque requête ?
    Salut à tous,

    Pour m'exercer avec Boost::Asio, j'ai écrit une classe Client (HTTP) en suivant l'exemple du site officiel (http://www.boost.org/doc/libs/1_35_0...ync_client.cpp).

    Ma classe présente ces méthodes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Client(boost::asio::io_service & io_service, const std::string & server);
    void Connect();
    void Disconnect();
    void Send(const std::string & command);
    Bref, du classique…

    Le problème, c'est que je ne parviens pas à utiliser cette classe de la façon attendue, c'est à dire :
    - Construction
    - Connexion
    - Envoi
    - Envoi
    - Envoi...
    - Déconnexion
    Je suis obligé de me reconnecter à chaque appel de Send(), sinon j'ai le droit à :
    Une tentative de connexion a échoué car le parti connecté n'a pas répondu convenablement au-delà d'une certaine durée ou une connexion établie a échoué car l'hôte de connexion n'a pas répondu
    Et effectivement, quand je sniffe avec Ethereal, le serveur m'envoie un [ACK, FIN] après la première requête TCP.

    C'est normal, docteur ?


    Évidemment, je vous joins mon code (épuré du superflu), vu que c'est certainement ici que ça pèche :
    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
     
    class Client
    {
        public:
            Client(boost::asio::io_service & io_service, const std::string & server);
            void Connect();
            void Disconnect();
            void Send(const std::string & command);
     
        private:
            boost::asio::io_service & io_service;
            std::string server;
            tcp::resolver::query query;
            tcp::socket socket;
            tcp::resolver resolver;
    };
    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
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    Client::Client(boost::asio::io_service & io_service, const std::string & server):
        io_service(io_service),
        server(server),
        query(server, "http"),
        socket(io_service),
        resolver(io_service)
    {
        Connect();
    }
     
    void Client::Connect()
    {
        /*
        Try each endpoint until we successfully establish a connection.
        Get a list of endpoints corresponding to the server name.
        */
        boost::system::error_code error = boost::asio::error::host_not_found;
        tcp::resolver::iterator end;
        for(tcp::resolver::iterator it = resolver.resolve(query); error && it != end; ++it) //loop until connection or no more endpoint
        {
            socket.close();
            socket.connect(*it, error);
        }
        if(error)
        {
            throw ConnectionException(server, boost::system::system_error(error).what());
        }
    }
     
    void Client::Disconnect()
    {
        socket.close();
    }
     
    void Client::Send(const std::string & command)
    {
        //Connect(); //obligé de décommenter cette ligne pour que ça fonctionne
     
        // Form the request. We specify the "Connection: close" header so that the
        // server will close the socket after transmitting the response. This will
        // allow us to treat all data up until the EOF as the content.
        boost::asio::streambuf request;
        std::ostream request_stream(&request);
        request_stream << "GET " << command << " HTTP/1.0\r\n";
        request_stream << "Host: " << server << "\r\n";
        request_stream << "Accept: */*\r\n";
        request_stream << "Connection: Keep-Alive\r\n\r\n";
     
        // Send the request.
        boost::asio::write(socket, request);
     
        // Read the response status line.
        boost::asio::streambuf response_streambuf;
        boost::asio::read_until(socket, response_streambuf, "\r\n");
     
        // Check that response is OK.
        std::istream response_stream(&response_streambuf);
        std::string http_version;
        response_stream >> http_version;
        unsigned int status_code;
        response_stream >> status_code;
        std::string status_message;
        std::getline(response_stream, status_message);
        if(!response_stream || http_version.substr(0, 5) != "HTTP/")
        {
            throw(InvalidResponseException(server));
        }
        if(status_code != 200)
        {
            throw(HttpException(server, status_code));
        }
     
        // Read the response headers, which are terminated by a blank line.
        boost::asio::read_until(socket, response_streambuf, "\r\n\r\n");
     
        // Read until EOF, writing data to output as we go.
        boost::system::error_code error;
        while (boost::asio::read(socket, response_streambuf, boost::asio::transfer_at_least(1), error));
        if(error != boost::asio::error::eof)
        {
            throw boost::system::system_error(error);
        }
    }

    Merci à tous ceux qui se creusent déjà la tête !

  2. #2
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Citation Envoyé par three minute hero Voir le message
    C'est normal, docteur ?
    Oui, c'est comme ça que ça fonctionne en HTTP.

    MAT.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 142
    Par défaut
    Ah.

    J'ai toujours utilisé des lib de plus haut niveau pour ce qui est du réseau, où la gestion au niveau du protocole est donc cachée.
    Un fait indéniable : programmer avec boost rend intelligent

    Merci beaucoup, Mat !

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

    Informations forums :
    Inscription : Février 2006
    Messages : 2 155
    Par défaut
    Boost c'est quand même du haut niveau aussi, tu codes pas le protocole toi-même !

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Février 2007
    Messages
    142
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 142
    Par défaut
    Certes certes

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Read until EOF sur une connexion keep-alive, tu vois pas le problème évident ?

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 23/10/2006, 16h02
  2. [Sécurité] Des \ avant chaque '
    Par ruty dans le forum Langage
    Réponses: 10
    Dernier message: 10/05/2006, 23h04
  3. Création de XMLHttpRequest à chaque requête sous IE
    Par mathieu dans le forum Général JavaScript
    Réponses: 13
    Dernier message: 17/11/2005, 12h11
  4. connection à chaque requête ou pas ?
    Par eschaer dans le forum Requêtes
    Réponses: 3
    Dernier message: 17/05/2005, 13h57
  5. Réponses: 2
    Dernier message: 02/11/2004, 06h52

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