boost::asio :: io_service.run() 需要很长时间才能 return 当主机详细信息有效但服务器端应用程序无效时 运行
boost::asio :: io_service.run() takes long time to return when host details are valid but server side application is not running
我是 network
、tcp
和 sockets programming
的新手。我在我的应用程序中使用 boost::asio
在 tcp/ip
协议上通过 wifi
处理数据。数据由主机 上的 另一个应用 运行 发送,其 IP 和端口在启动期间为我的应用所知。应用程序连接到此 HostApp
以在运行时获取数据。
以下是我的应用程序中连接到主机的一段代码:
std::shared_ptr<tcp::resolver> resolver = std::make_shared<tcp::resolver>(io_service);
tcp::resolver::query tcp_query(IP_Address, Port_Number);
boost::system::error_code host_resolve_error;
tcp::resolver::iterator destination = resolver->resolve(tcp_query, host_resolve_error);
socket.reset(new tcp::socket(io_service));
if (host_resolve_error) {
std::cout << "IP & port inputted could not be resolved" << std::endl;
return false;
}
auto connection_state_callback_handler = [this]
(const boost::system::error_code& error_code, const tcp::resolver::iterator& it)
{
if (error_code){
//Error has occurred. Abort or retry
connection_set = false;
}
else {
if (it == tcp::resolver::iterator()) {
//Some logic
connection_set = false;
}
else {
connection_set = true;
std::cout << "Callback received for socket connected" << std::endl;
//Small test to check my data header to confirm that connection is set
MyDataHeader data_head;
boost::asio::read(*m_socket, boost::asio::buffer(& data_head, sizeof(data_head)));
}
}
};
//call boost asynchronous connect passing it a handler as it needs to report back when ready
boost::asio::async_connect(*m_socket, destination, tcp::resolver::iterator(), connection_state_callback_handler);
io_service.run(); //Takes long time to return when HostApp is not running
StartMyDataThread_WhichPollsData_InALoop();
只要输入的 ip & port
正确加上 HostApp
是 运行,上面的代码就能快速连接并正常工作。如果我输入 malformed/irresolvable ip+port 然后,host_resolve_error
得到一个值并且我 return 立即输出。感谢以下区块
if (host_resolve_error) {
std::cout << "IP & port inputted could not be resolved" << std::endl;
return false;
}
但这是我面临的问题: 当输入的 ip & port
是有效的加上我的 HostApp
不是 运行在服务器端,然后 io_service.run()
需要很长时间,比如 20-30 秒到 return。这对我的应用程序有害。
是否有 io_service
的其他 API 我可以在其中设置 time_out
并获得与 io_service.run()
相同的功能?或者其他一些快速确定我的 HostApp
不是 运行 的方法?
我尝试了很多东西来尝试解决:
1. 我尝试将 io_service.run()
传递给 std::async
如下所示,但不起作用
auto handle = std::async(std::launch::async, [this]{ io_service.run( ); });
2. 我试图调用 io_service.run_one()
而不是 io_service.run()
。这个也需要时间return
解决这个问题的最佳方法是什么?即使它无法设置连接,我也需要快速 io_service.run()
到 return。如何向 io_service.run()
添加 time_out 机制?
您只需将 io_service 的实例添加到构造函数的截止时间计时器中。所以导入 <boost/asio/deadline_timer.hpp>
并构建你的 io_service 就像:
client(boost::asio::io_service& io_service)
: stopped_(false),
socket_(io_service),
deadline_(io_service),
heartbeat_timer_(io_service)
{
}
然后您可以稍后在代码中调用它,例如:
deadline_.expires_from_now(boost::posix_time::seconds(60));
我是 network
、tcp
和 sockets programming
的新手。我在我的应用程序中使用 boost::asio
在 tcp/ip
协议上通过 wifi
处理数据。数据由主机 上的 另一个应用 运行 发送,其 IP 和端口在启动期间为我的应用所知。应用程序连接到此 HostApp
以在运行时获取数据。
以下是我的应用程序中连接到主机的一段代码:
std::shared_ptr<tcp::resolver> resolver = std::make_shared<tcp::resolver>(io_service);
tcp::resolver::query tcp_query(IP_Address, Port_Number);
boost::system::error_code host_resolve_error;
tcp::resolver::iterator destination = resolver->resolve(tcp_query, host_resolve_error);
socket.reset(new tcp::socket(io_service));
if (host_resolve_error) {
std::cout << "IP & port inputted could not be resolved" << std::endl;
return false;
}
auto connection_state_callback_handler = [this]
(const boost::system::error_code& error_code, const tcp::resolver::iterator& it)
{
if (error_code){
//Error has occurred. Abort or retry
connection_set = false;
}
else {
if (it == tcp::resolver::iterator()) {
//Some logic
connection_set = false;
}
else {
connection_set = true;
std::cout << "Callback received for socket connected" << std::endl;
//Small test to check my data header to confirm that connection is set
MyDataHeader data_head;
boost::asio::read(*m_socket, boost::asio::buffer(& data_head, sizeof(data_head)));
}
}
};
//call boost asynchronous connect passing it a handler as it needs to report back when ready
boost::asio::async_connect(*m_socket, destination, tcp::resolver::iterator(), connection_state_callback_handler);
io_service.run(); //Takes long time to return when HostApp is not running
StartMyDataThread_WhichPollsData_InALoop();
只要输入的 ip & port
正确加上 HostApp
是 运行,上面的代码就能快速连接并正常工作。如果我输入 malformed/irresolvable ip+port 然后,host_resolve_error
得到一个值并且我 return 立即输出。感谢以下区块
if (host_resolve_error) {
std::cout << "IP & port inputted could not be resolved" << std::endl;
return false;
}
但这是我面临的问题: 当输入的 ip & port
是有效的加上我的 HostApp
不是 运行在服务器端,然后 io_service.run()
需要很长时间,比如 20-30 秒到 return。这对我的应用程序有害。
是否有 io_service
的其他 API 我可以在其中设置 time_out
并获得与 io_service.run()
相同的功能?或者其他一些快速确定我的 HostApp
不是 运行 的方法?
我尝试了很多东西来尝试解决:
1. 我尝试将 io_service.run()
传递给 std::async
如下所示,但不起作用
auto handle = std::async(std::launch::async, [this]{ io_service.run( ); });
2. 我试图调用 io_service.run_one()
而不是 io_service.run()
。这个也需要时间return
解决这个问题的最佳方法是什么?即使它无法设置连接,我也需要快速 io_service.run()
到 return。如何向 io_service.run()
添加 time_out 机制?
您只需将 io_service 的实例添加到构造函数的截止时间计时器中。所以导入 <boost/asio/deadline_timer.hpp>
并构建你的 io_service 就像:
client(boost::asio::io_service& io_service)
: stopped_(false),
socket_(io_service),
deadline_(io_service),
heartbeat_timer_(io_service)
{
}
然后您可以稍后在代码中调用它,例如:
deadline_.expires_from_now(boost::posix_time::seconds(60));