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 :

"Recharger" un deadline_timer


Sujet :

Boost C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juillet 2009
    Messages : 31
    Points : 28
    Points
    28
    Par défaut "Recharger" un deadline_timer
    Bonjour,

    pour détecter les timeouts de mon serveur, j'utilise un deadline_timer de boost::asio.

    Alors j'ai mon timer lié a ma méthode callback comme ca (dans le constructeur de ma connection):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    timer.async_wait(boost::bind(&tftp_connection::timeout_callback , this));
    Et lorsque j'envoie des données, j'attends confirmation de la réception.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    timer.expires_from_now(boost::posix_time::milliseconds(TIMER_DURATION));
    Le timer est assez important, 5 secondes, il ne devrait pas être atteint dans mes tests actuels:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const int TIMER_DURATION = 5000; // ms
    Et ma callback ne fait pas grand-chose pour le moment:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void tftp_connection::timeout_callback()
    {
        std::cout << "Time Out !\n";
    }
    Mon problème:
    A chaque recharge du timer, la callback est appelée, et je n'ai pas trouver le moyen de différencier le timeout atteint et le rechargement du timer.
    Comment je dois m'y prendre ?

    Merci !

    EDIT: Ah... En fait, il ne passe qu'une fois dans ma callback, mais au tout début de la connection...

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juillet 2009
    Messages : 31
    Points : 28
    Points
    28
    Par défaut
    En me basant sur cet exemple du tutoriel Boost::Asio d'ici:
    http://gwenael-dunand.developpez.com.../asio/#LIV-E-3

    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
    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 do_read() // (1)
    	{
    		// On lance une écoute
    		boost::asio::async_read(m_socket, boost::asio::buffer(m_buffer), // (3)
    			boost::bind(&tcp_connection::handle_read, shared_from_this(),
    			boost::asio::placeholders::error)
    			);
    		timer.expires_from_now(boost::posix_time::seconds(5)); // (4)
    		timer.async_wait(boost::bind(&tcp_connection::close, shared_from_this() )); //(5)
    	}
     
     
    	void 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)
    			);
    	}
     
    private:	
    	tcp_connection(boost::asio::io_service& io_service) 
    		: m_socket(io_service), 
    		timer(io_service, boost::posix_time::seconds(5)) // Commence à compter dès sa création
    	{
    	}
     
    	void handle_write(const boost::system::error_code& error)
    	{
    		if (!error)
    		{
    			do_read(); // (2)
    		}
    		else {
    			std::cout << error.message() << std::endl;
    		}
    	}
     
    	void handle_read(const boost::system::error_code& error) // (6)
    	{
    		if (!error)
    		{
    			// On réécoute
    			do_read();
    		}
    		else 
    		{
    			close();
    		}
    	}
     
    	void close() // (7)
    	{
    		m_socket.close();
    	}
     
    	boost::asio::deadline_timer timer;
    	tcp::socket m_socket;
    	std::string m_message;
    	boost::array<char, 128> m_buffer;
    };
    Et la définition sur le site de Boost:
    This function sets the expiry time. Any pending asynchronous wait operations will be cancelled. The handler for each cancelled operation will be invoked with the boost::asio::error::operation_aborted error code.

    Ce bout de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    timer.expires_from_now(boost::posix_time::seconds(5)); // (4)
    timer.async_wait(boost::bind(&tcp_connection::close, shared_from_this() )); //(5)
    Devrait fermer la connection dès le premier appel puisqu'il appelle la callback (close).

    Y a-t-il une erreur dans l'exemple (sur lequel je me base) ?

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juillet 2009
    Messages
    31
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juillet 2009
    Messages : 31
    Points : 28
    Points
    28
    Par défaut
    Alors, j'ai ajouté le code erreur dans ma call back, comme ca:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void tftp_connection::timeout_callback(const boost::system::error_code& e)
    {
        if (e == boost::asio::error::operation_aborted)
            std::cout << "Cancel\n";
        else
            std::cout << "Time Out\n";
    }
    Et j'ai modifié mon bind en conséquence:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    timer.async_wait(boost::bind(&tftp_connection::timeout_callback , this, boost::asio::placeholders::error));
    Et tout fonctionne comme attendu !

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

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