|
Boost : |
Subject: [boost] [asio]How add a timeout to asio connection?
From: Renato Forti (re.tf_at_[hidden])
Date: 2013-06-25 08:51:33
Hi All,
I have one problem, I have this class to connect to my server app:
class session
{
public:
static void init(
const std::string& host,
const std::string& port,
hades::archive::archive& iarch,
hades::archive::archive& oarch)
{
boost::asio::io_service io_service;
client client(io_service, host, port, iarch, oarch);
io_service.run();
}
};
The problem is : if my server is down, my client (session) will block on
io_service.run(); the client nerves end. Then I try to add a time out:
class client
{
public:
/// Constructor starts the asynchronous connect operation.
client(boost::asio::io_service& io_service,
const std::string& host,
const std::string& port, // service
hades::archive::archive& iarch,
hades::archive::archive& oarch)
: connection_(io_service)
, deadline_(io_service)
, iarch_(&iarch)
, oarch_(&oarch)
{
deadline_.async_wait(boost::bind(&client::check_deadline, this));
deadline_.expires_from_now(boost::posix_time::seconds(30));
// Resolve the host name into an IP address.
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query(host, port);
boost::asio::ip::tcp::resolver::iterator endpoint_iterator
= resolver.resolve(query);
// Start an asynchronous connect operation.
boost::asio::async_connect(connection_.socket(), endpoint_iterator,
boost::bind(&client::handle_connect, this,
boost::asio::placeholders::error));
}
/// Handle completion of a connect operation.
void handle_connect(const boost::system::error_code& e)
{
if (!e)
{
// Successfully established connection. Start operation to read the
list
// of stocks. The connection::async_read() function will
automatically
// decode the data that is read from the underlying socket.
connection_.async_read(*oarch_,
boost::bind(&client::handle_read, this,
boost::asio::placeholders::error));
connection_.async_write(*iarch_,
boost::bind(&client::handle_write, this,
boost::asio::placeholders::error)) ;
}
else
{
// An error occurred.
throw sync_client_exception(e.message());
}
}
// Handle completion of a write operation.
void handle_write(const boost::system::error_code& e)
{
}
// Handle completion of a read operation.
void handle_read(const boost::system::error_code& e)
{
}
void check_deadline()
{
// Check whether the deadline has passed. We compare the deadline
against
// the current time since a new asynchronous operation may have moved
the
// deadline before this actor had a chance to run.
if (deadline_.expires_at() <= deadline_timer::traits_type::now())
{
// The deadline has passed. The socket is closed so that any
outstanding
// asynchronous operations are cancelled.
connection_.socket().close();
// There is no longer an active deadline. The expiry is set to
positive
// infinity so that the actor takes no action until a new deadline
is set.
deadline_.expires_at(boost::posix_time::pos_infin);
throw sync_client_exception("Time out : deadline on client!");
}
// Put the actor back to sleep.
deadline_.async_wait(boost::bind(&client::check_deadline, this));
}
private:
// The connection to the server.
dsafe::sync::connection connection_;
// The data received from the server.
hades::archive::archive *iarch_;
hades::archive::archive *oarch_;
deadline_timer deadline_;
};
The problem is that now the timeout expires even if the connection to the
server occurs. What is wrong?
My timeout should be disabled when the connection is successful! How do I
get it? Only when the connection fails it should be called!
Thanks for clarification
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk