我一直在寻找一种方法来取消 Boost ASIO 读取或写入操作,如果它占用了一定的时间。我的服务器正在发送 HTTP 请求,并从这些请求中读取结果,所以我最初将其编码为同步读/写,如果需要这么长时间,我会继续执行并在结果返回时忽略它们。如果服务器出现故障,这会导致问题,我的服务器会打开许多套接字,并且会崩溃。所以我决定如果延迟太长我想取消读/写,但显然同步读/写不能在不破坏它们正在运行的线程的情况下被取消,我不想这样做。所以我找到了一篇关于如何用异步调用模拟同步读/写并取消超时调用的帖子。 这个 是我关注的帖子。我知道这篇文章已经相当老了,所以我不确定自那个版本和我正在使用的版本(1.48)以来函数调用是否发生了变化,但这似乎并不完全正确。这是我的代码
bool connection::query_rtb(const std::string &request_information, std::string &reply_information)
{
try
{
boost::optional<boost::system::error_code> timer1_result, timer2_result, write_result, read_result;
boost::array<char,8192> buf;
buf.assign(0);
boost::asio::deadline_timer dt(io_service_);
dt.expires_from_now(boost::posix_time::milliseconds(100));
dt.async_wait(boost::bind(&connection::set_result, this, &timer1_result, _1, "timer1"));
boost::asio::async_write(socket_, boost::asio::buffer(request_information, request_information.size()), boost::bind(&connection::set_result, this, &write_result, _1, "write"));
io_service_.reset();
while(io_service_.run_one())
{
if(write_result)
{
dt.cancel();
}
else if(timer1_result)
{
socket_.cancel();
}
}
boost::asio::deadline_timer dt2(io_service_);
dt2.expires_from_now(boost::posix_time::milliseconds(3000));
dt2.async_wait(boost::bind(&connection::set_result, this, &timer2_result, _1, "timer2"));
boost::asio::async_read(socket_, boost::asio::buffer(buf), boost::bind(&connection::set_result, this, &read_result, _1, "read"));
//socket_.async_receive(boost::asio::buffer(buf), boost::bind(&connection::set_result, this, &read_result, _1, "read"));
io_service_.reset();
while(io_service_.run_one())
{
if(read_result)
{
dt2.cancel();
}
if(timer2_result)
{
socket_.cancel();
}
}
reply_information = buf.data();
std::cout << reply_information << std::endl;
return true;
}catch(std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
void persistent_connection::set_result(boost::optional<boost::system::error_code> *a, boost::system::error_code ec, std::string t)
{
std::cout << t << std::endl;
a->reset(ec);
}
我想知道是否有人看到此代码有任何问题,或者对它为什么不起作用有任何想法。目前写入似乎很好,但是直到 dt2 完成它的计时器之后才会读取。如果您需要更多信息,请告诉我,我很乐意提供一些信息。
编辑:
好像我得到了它的工作测试我认为我以前测试过的东西。使用async_receive
而不是async_read
似乎解决了我遇到的任何问题。任何线索为什么这会导致我的问题?我想知道我的逻辑是否有问题,或者这是否是async_read
通常的行为方式。