当服务器不正常关闭时,boost.asio异步写入超时不起作用



我参考了boost示例中的示例:async_tcp_client.cpp。这个示例显示了如何设置aync_read的超时。因此,我根据这个例子编写了一个测试程序来测试async_write超时。写入代码为:

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;
}

handleWrite代码为:

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());
}

根据我的测试,如果我禁用网络或拔出运行服务器的PC的电缆,async_write将始终正常完成,因此超时设置不起作用。我想知道我是否错过了什么,希望熟悉这方面的人能给我一些线索,谢谢你的提前通知!


更新

异步等待代码:

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));
}

我把io_context的run方法放在了一个线程中,我不确定这是否是正确的方法,因为我不想在main函数中运行io_context.run((。

void AsioAsyncTCPClientImpl::loopProcess()
{
while(m_started)
{
m_context.run();
}
std::cout << "loop process exited" << std::endl;
}

您从不等待计时器。

类似的东西

m_deadline.async_wait(
std::bind(&AsioAsyncTCPClientImpl::handleTimer, this, boost::asio::placeholders::errpr));

然后

void AsioAsyncTCPClientImpl::handleTimer(boost::system::error_code ec) {
if (!ec) {
std::cout << "Timeout expired" << std::endl;        
m_client.cancel();
}
}

最新更新