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 => récupérer les données d'une socket


Sujet :

Boost C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 106
    Points : 50
    Points
    50
    Par défaut Boost::asio => récupérer les données d'une socket
    Bonjour,

    J'utilise boost::asio et j'aimerai récupérer ce que me retourne une socket dans un string

    J'ai trouvé sur leur site un exemple de code client HTTP, dont le code pour récupérer les infos est le suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    while (boost::asio::read(socket, response,
              boost::asio::transfer_at_least(1), error))
          std::cout << &response;
     
    if (error != boost::asio::error::eof)
          throw boost::system::system_error(error);
    Ce code marche parfaitement mais il m'affiche les infos. Or je voudrai tout mettre dans un string.

    J'ai vu qu'on pouvait faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    string contenuPage, s;
    while (boost::asio::read(socket, response,
              boost::asio::transfer_at_least(1), error))
    {
          std::istream is(&response);
          is >> s;
          contenuPage += s;
    }
    Mais ça ne marche pas comme je veux. En fait, ça me lit les données mot par mot (donc c'est pas super si j'ai une longue page web), et ça ne me lit pas toute la page !

    Y'a-t-il un moyen plus simple (que je n'aurais pas vu) pour collecter les données ?

    Merci d'avance

  2. #2
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Personnellement, j'aime bien utiliser les iostreams de Asio

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 106
    Points : 50
    Points
    50
    Par défaut
    Merci, mais je ne vois pas trop comment m'en servir. Il y a assez peu de méthodes je trouve : http://www.boost.org/doc/libs/1_37_0.../iostream.html

    Quant à l'exemple que tu m'as montré, j'ai essayé de remplacer daytime par http, ou même de supprimer carrément ce paramètre, mais ça ne marche pas

  4. #4
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    suffit de mettre "leport" au lieu de "daytime".
    Par exemple : "80" pour du HTTP

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 106
    Points : 50
    Points
    50
    Par défaut
    ça ne marche toujours pas

    En fait ça bloque sur le getline :
    tcp::iostream s("www.isima.fr", "80");
    std::string line;
    std::getline(s, line);

  6. #6
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Si tu veux le contenu de la page, il faut envoyer une requête GET en suivant le protocole.

    Cf :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        boost::asio::streambuf request;
        std::ostream request_stream(&request);
        request_stream << "GET " << argv[2] << " HTTP/1.0\r\n";
        request_stream << "Host: " << argv[1] << "\r\n";
        request_stream << "Accept: */*\r\n";
        request_stream << "Connection: close\r\n\r\n";
    dans : http://www.boost.org/doc/libs/1_38_0...ync_client.cpp

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 106
    Points : 50
    Points
    50
    Par défaut
    oui c'est bien ce que j'ai fait

    EDIT : adressePage et serveur sont des string définis avant, et serveur a pour valeur www.isima.fr

    Voici le code :
    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
    boost::asio::io_service ioService;
        /* Création d'une socket et connexion au serveur */
        tcp::socket * socket = connexionSocket(serveur, ioService);
     
        boost::asio::streambuf request;
        ostream requestStream(&request);
     
        /* Ecriture dans le requestStream des requêtes HTTP */
        requestStream << "GET " << adressePage << " HTTP/1.0\r\n";
        requestStream << "Host: " << serveur << "\r\n";
        requestStream << "Accept: */*\r\n";
        requestStream << "Connection: close\r\n\r\n";
     
        /* Envoi des requêtes */
        boost::asio::write(*socket, request);
     
        /* Lecture du numéro de version HTTP et du code HTTP renvoyé */
        boost::asio::streambuf response;
        boost::asio::read_until(*socket, response, "\r\n");
     
        istream responseStream(&response);
        string httpVersion;
        responseStream >> httpVersion;
     
        unsigned int statusCode;
        responseStream >> statusCode;
     
        string statusMessage;
        getline(responseStream, statusMessage);
     
        if (!responseStream || httpVersion.substr(0, 5) != "HTTP/")
            throw SocketRepInvalide("Réponse du serveur invalide");
        if (statusCode != 200)
            throw SocketRepInvalide("Code de réponse du serveur incorrect");
     
        /* Lecture du header */
        boost::asio::read_until(*socket, response, "\r\n\r\n");
        std::string header;
        while (std::getline(responseStream, header) && header != "\r");
     
     
        /* Lecture du contenu de la page */
        boost::system::error_code error;
        string contenuPage;
        tcp::iostream s("www.isima.fr", "80");
        while (boost::asio::read(*socket, response, boost::asio::transfer_at_least(1), error))
        {
     
            std::string line;
            std::getline(s, line);
            contenuPage += line;
        }
     
     
        if (error != boost::asio::error::eof)
            throw boost::system::system_error(error);
    EDIT : après 2 journées passées sur ce problème j'ai toujours pas de solution. Ils ont pas pensé à faire une méthode qui renvoie un string ?

  8. #8
    Membre expérimenté

    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
    Points : 1 543
    Points
    1 543
    Par défaut
    Salut,

    Essaye un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        boost::asio::streambuf response;
        std::stringstream s;
        s << &response;
        const std::string tadaa = s.str()
    MAT.

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 106
    Points : 50
    Points
    50
    Par défaut
    Super merci ça marche

    Dans un soucis d'optimisation j'aimerais savoir si tu connais un moyen pour ne déclarer qu'un seul stringstream, au lieu d'en déclarer un à chaque tour de boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    while (boost::asio::read(*socket, response, boost::asio::transfer_at_least(1), error))
        {
            std::stringstream s;
            s << &response;
            const std::string tadaa = s.str();
            cout << "TADA ::: " << tadaa << endl;
        }
    J'ai bien essayé d'appeler s.flush(); ou de faire s << "" à la fin de chaque tour de boucle. Mais le problème dans ce cas c'est que l'objet s garde le contenu précédent de response. Donc j'ai un affichage multiple

  10. #10
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    .clear() ? (de mémoire)

  11. #11
    Membre expérimenté

    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
    Points : 1 543
    Points
    1 543
    Par défaut
    Pour vider un std::stringstream il faut faire :
    (clear c'est pour les flags)

    MAT.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    106
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 106
    Points : 50
    Points
    50
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Pour vider un std::stringstream il faut faire :
    (clear c'est pour les flags)

    MAT.
    Parfait merci beaucoup


    Alp peux-tu me dire ce qui n'allait pas quand j'essayais d'utiliser l'iostream stp ? parce que les exemples que je voyais sur le net étaient pourtant bien les mêmes que ce que tu m'a montré, donc je comprends pas pourquoi ça marche pas

  13. #13
    Alp
    Alp est déconnecté
    Expert éminent sénior

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Points : 11 860
    Points
    11 860
    Par défaut
    Tu mélangeais simplement les différentes façons de communiquer sur le réseau, en t'inspirant d'examples et d'autres de la doc.

    Il vaut peut-être mieux que tu te contentes de la méthode classique, et tu verras pour les streams plus tard

Discussions similaires

  1. Réponses: 5
    Dernier message: 07/09/2006, 14h41
  2. récupérer les données d'une fenetre
    Par snoopo dans le forum Interfaces Graphiques en Java
    Réponses: 5
    Dernier message: 23/06/2006, 17h23
  3. Réponses: 15
    Dernier message: 20/06/2006, 10h29
  4. Récupérer les données après une recherche
    Par cdumas dans le forum Access
    Réponses: 7
    Dernier message: 04/05/2006, 12h09
  5. Récupérer les données d'une iframe
    Par juli1 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 4
    Dernier message: 09/02/2005, 22h53

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