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

Bibliothèques Discussion :

Boost : threads et sockets


Sujet :

Bibliothèques

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 5
    Points : 8
    Points
    8
    Par défaut Boost : threads et sockets
    Bonjour,

    Je suis plutôt un débutant en c++ et j'ai quelques problèmes avec la manipulation de boost::thread et boost::socket.
    En gros le principe de ce que je dois écrire :
    J'ai un serveur qui écoute sur un port prédéfini en TCP et dès qu'il a une connection entrante, il refile la socket à un thread travailleur qu'il crée au passage. Celui s'occupe de la discussion avec le client.
    Jusqu'ici tout est simple et ce que j'ai fait marche presque (comprenez, ca compile, ca se lance et ca marche jusqu'à la 4-5ème connexion ou le serveur plante avec l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    terminate called after throwing an instance of 'boost::system::system_error'
      what():  Bad file descriptor
    Apparemment, la socket s'est fermée avant d'arriver entre les mains du thread d'où le plantage (le code de l'erreur retournée est system:9 mais je n'en sais pas plus. Je n'ai toujours pas réussi à trouver une table de correspondance exhaustive des codes d'erreur de boost :s).

    J'ai donc du faire un truc qui marche à peu près mais qui doit être affreusement mal foutu au niveau conceptuel.

    Je vais vous résumer mon code : en gros mon serveur fait :

    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
     
    void serveur::start_serveur() {
    boost::asio::io_service io_service;
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), monport));
     
    	for (;;)
        {
          tcp::socket socket(io_service);
          // On attend un client...
          acceptor.accept(socket);
     
          // Là on refile le travail à un thread travailleur
    	  Tache todo(&socket);
    	  boost::thread doit(todo);
     
       }
    Et voici l'opérateur "()" du foncteur Tache :

    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
    void Tache::operator() () {
     for (;;)
        {
          boost::array<char, 128> buf;
          boost::system::error_code error;
          size_t len = (*masocket).read_some(boost::asio::buffer(buf), error);
          if (error == boost::asio::error::eof)
            break; // Connection closed cleanly by peer.
          else if (error)
            throw boost::system::system_error(error); // Some other error.
          std::cout.write(buf.data(), len);
        }
     
    (*masocket).close();
     
    }
    Bon, comme vous l'aurez remarqué (ou pas), une grosse partie du code vient directement des exemples de boost mais ma priorité pour le moment est de clarifier le fonctionnement des sockets et de faire une architecture serveur->thread_travailleur simple et fonctionnelle.

    Mon client, de son coté fait simplement une ouverture de socket puis une écriture :

    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
    using boost::asio::io_service io_service;
     
        tcp::resolver resolver(io_service);
        tcp::resolver::query query(argv[1], "daytime");
        tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
        tcp::resolver::iterator end;
     
        tcp::socket socket(io_service);
        boost::system::error_code error = boost::asio::error::host_not_found;
        while (error && endpoint_iterator != end)
        {
          socket.close();
          socket.connect(*endpoint_iterator++, error);
        }
        if (error)
          throw boost::system::system_error(error);
     
        boost::system::error_code ignored_error;
    	std::string message = "HELLO";
    	boost::asio::write(socket, boost::asio::buffer(message),boost::asio::transfer_all(), ignored_error);
    Voilà un peu tout (et félicitations à ceux qui auront lu jusque là ).
    Mon gros problème est de comprendre les conditions de fermeture d'une socket. Dans mon esprit, les choses ne sont pas claires :
    Je ne donne l'ordre à ma socket de se fermer qu'à la fin de la lecture du serveur mais il est clair que ca ne suffit pas : la socket se ferme d'elle même pour une raison inconnue.
    À un moment, j'avais tenté l'opération inverse : le client écrit dans la socket et le serveur lit. À ce moment, le comportement était pour le moins étrange : si je demandais au thread principal de lire le socket, tout marchait mais si j'attendais que le thread travailleur s'occupe de la socket et qu'il la lise lui-même, j'obtenais un erreur (la socket s'étant fermée d'elle même et ce systématiquement ?!?!?).
    Au passage :
    - Si je ferme la socket avec close() d'un coté, cela ferme-t-il également la socket de l'autre coté (a priori je ne vois pas de raison pour que ce soit le cas mais bon...)
    - Si j'appelle close(), cela appelle-t-il ~socket (si la méthode existe ?) par la même occasion ?

    Merci beaucoup d'avance pour toute réponse qui me permettra d'y voir un peu plus clair...

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 5
    Points : 8
    Points
    8
    Par défaut
    En fait, plus de problèmes. C'était juste un problème tout bête (variable temporaire de boucle pour le socket).

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

Discussions similaires

  1. Boost : thread et sockets
    Par Alpha573 dans le forum Threads & Processus
    Réponses: 26
    Dernier message: 26/01/2011, 15h47
  2. [Débutant] boost::thread non-lvalue
    Par Tymk dans le forum Boost
    Réponses: 16
    Dernier message: 18/11/2006, 14h23
  3. Questions de perfomance avec boost::thread
    Par Rafy dans le forum Boost
    Réponses: 36
    Dernier message: 05/10/2006, 15h21
  4. boost::thread et OpenGL
    Par Kurisu dans le forum Boost
    Réponses: 12
    Dernier message: 19/09/2006, 13h23

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