我正在编写一个连接管理器类,它应该建立到服务器的连接,并使用Boost发送几个HTTP请求。Beast。它有一个connect
方法,如果连接成功,应该返回true
,否则返回false
。我正在使用tcp_stream
和它的async_connect
方法与boost::asio::use_future
到wait_for
某种类型,并检查连接是否未能及时建立。
我的connect
方法有以下代码:
// ...
const auto resolve = this->resolver.resolve(this->host, this->port);
auto connect_future = this->stream.async_connect(resolve, boost::asio::use_future);
switch (connect_future.wait_for(boost::asio::chrono::seconds{5})) {
// Do the work
}
// ...
与reolver
和stream
关联的io_context
的事件循环在事件循环线程中不断调用其run
方法。它建立连接并工作,但总是等待整整5秒,直到继续。我做错了什么?
edit:在尝试创建一个最小可重复的示例时,我偶然发现了以下内容:代码在使用-DWORKING
编译时干净地退出,并在没有它的情况下打印Timeout
!
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/use_future.hpp>
#include <boost/asio/strand.hpp>
#include <atomic>
#include <iostream>
#include <string>
// Performs an HTTP GET and prints the response
int main(int argc, char** argv)
{
namespace net = boost::asio;
namespace beast = boost::beast;
net::io_context ioc;
std::atomic_bool running = true;
std::thread loop([&ioc, &running] {
while (running) {
ioc.run();
}
});
net::ip::tcp::resolver resolver(net::make_strand(ioc));
beast::tcp_stream stream(net::make_strand(ioc));
const auto resolve = resolver.resolve("127.0.0.1", "8080");
auto fut = stream.async_connect(resolve, net::use_future);
switch (fut.wait_for(net::chrono::seconds(5))) {
case std::future_status::timeout:
std::cerr << "Timelimit" << std::endl;
break;
default: break;
}
running = false;
loop.join();
stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both);
ioc.stop();
return 0;
}
edit 2:更像我的实际代码的东西。然而,这不受该问题的影响。我是不是遇到了UB?
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/connect.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/use_future.hpp>
#include <boost/asio/strand.hpp>
#include <atomic>
#include <iostream>
#include <string>
// Performs an HTTP GET and prints the response
int main(int argc, char** argv)
{
namespace net = boost::asio;
namespace beast = boost::beast;
net::io_context ioc;
std::atomic_bool running = true;
std::thread loop([&ioc, &running] {
while (running) {
ioc.run();
}
});
net::ip::tcp::resolver resolver(net::make_strand(ioc));
beast::tcp_stream stream(net::make_strand(ioc));
const auto resolve = resolver.resolve("127.0.0.1", "8080");
auto fut = stream.async_connect(resolve, net::use_future);
switch (fut.wait_for(net::chrono::seconds(5))) {
case std::future_status::timeout:
std::cerr << "Timelimit" << std::endl;
break;
default: break;
}
running = false;
loop.join();
stream.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both);
ioc.stop();
return 0;
}
1条答案
按热度按时间qltillow1#
只有当服务在不同的线程上运行时,Future才有意义。
您的线程不能保证工作:
文档解释说,如果
run()
用完了工作,restart()
将需要重新启动它。这意味着线程只会运行一个紧密的循环而没有任何效果(除了加热CPU)。使用
work_guard
或thread_pool
:或者
这样做的好处是,您不需要修复手写的线程来处理异常(Should the exception thrown by boost::asio::io_service::run() be caught?)。