如果需要花费一定的时间,我一直在寻找一种取消Boost ASIO读或写操作的方法。我的服务器正在发送HTTP请求,并从这些请求中读取结果,因此我最初将其编码为同步读/写,如果花了这么长时间,我只会继续并在它们返回时忽略结果。如果服务器出现故障,我的服务器将打开许多套接字,并且会崩溃,这会导致问题。所以我决定如果有太长的延迟我想取消读/写,但显然同步读/写不能在不破坏它们运行的线程的情况下被取消,这是我不想做的。所以我发现了一篇关于如何模仿异步调用的同步读/写并在超时时取消调用的帖子。 This 是我跟随的帖子。我知道这篇文章相当陈旧,所以我不确定函数调用是否会因为该版本和我正在使用的函数(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
通常会如何处理。
答案 0 :(得分:1)
boost::array<char,8192> buf;
...
boost::asio::async_read(socket_, boost::asio::buffer(buf), boost::bind(&connection::set_result, this, &read_result, _1, "read"));
您已指示程序从套接字读取8192个字节。如果将逻辑从使用async_read()
自由函数切换到async_receive()
成员函数可以解决此问题,请参阅the documentation
说明
接收操作可能无法接收所有请求的号码 字节。如果需要确保,请考虑使用
async_read
功能 在异步之前接收所请求的数据量 操作完成。