I refer to the example from boost example: async_tcp_client.cpp . This example shows how to set timeout for aync_read. So I write a test program to test async_write timeout according to this example. The write code is:
bool AsioAsyncTCPClientImpl::send(const uint8_t* data, int32_t length)
{
if (!m_isConnected || length <= 0) return false;
m_deadline.expires_after(std::chrono::seconds(5));
boost::system::error_code ec;
boost::asio::async_write(m_client, boost::asio::buffer(data, length),
std::bind(&AsioAsyncTCPClientImpl::handleWrite, this, std::placeholders::_1, std::placeholders::_2));
return true;
}
the handleWrite code is:
void AsioAsyncTCPClientImpl::handleWrite(const boost::system::error_code& ec, std::size_t len)
{
if (!m_started) return;
if (ec == boost::asio::error::eof)
{
fireConnectionCallback(ConnectionState::Disconnected);
return;
}
if (ec)
{
fireErrorCallback(ec);
return;
}
m_deadline.expires_at(boost::asio::steady_timer::time_point::max());
}
From my test, if I disable the network or pull out the cable of the PC where the server is running, the async_write will always completed as normal, so the timeout set is not working. I am wondering if I miss something, hope some one familiar with this could give me some clue, Thanks for advance!
The async_wait code:
bool AsioAsyncTCPClientImpl::start()
{
if (m_started) return true;
connect();
m_deadline.async_wait(std::bind(&AsioAsyncTCPClientImpl::checkTimeout, this));
m_started = true;
m_ioLoopThread = std::thread(&AsioAsyncTCPClientImpl::loopProcess, this);
return true;
}
void AsioAsyncTCPClientImpl::checkTimeout()
{
if (!m_started) return;
if (m_deadline.expiry() <= boost::asio::steady_timer::clock_type::now())
{
std::cout << "wait timeout" << std::endl;
disconnect();
m_deadline.expires_at(boost::asio::steady_timer::time_point::max());
}
m_deadline.async_wait(std::bind(&AsioAsyncTCPClientImpl::checkTimeout, this));
}
And I put the run method of io_context in a thread, I am not sure if this is right way to do it, because I don't want to run io_context.run() in main function.
void AsioAsyncTCPClientImpl::loopProcess()
{
while(m_started)
{
m_context.run();
}
std::cout << "loop process exited" << std::endl;
}
You never await the timer.
Something like
m_deadline.async_wait(
std::bind(&AsioAsyncTCPClientImpl::handleTimer, this, boost::asio::placeholders::errpr));
And then
void AsioAsyncTCPClientImpl::handleTimer(boost::system::error_code ec) {
if (!ec) {
std::cout << "Timeout expired" << std::endl;
m_client.cancel();
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.