我最近遇到了boost :: asio异步任务的问题。我想返回一个指向侦听端口的对象的指针。 它适用于我使用socket.read_some方法,但此方法阻止我的主,我希望我的MyClass :: create方法返回。Boost Asio - 为什么我的异步操作无法启动?
所以我尝试了一个async_read调用,但是我看到在我的read()方法中没有启动异步任务。我试图找出可能导致问题的原因,但看不到这个问题的解决方案。
这是我的代码,在这里它没有async_read,但有一个async_wait,并且出现同样的问题,定时器不会启动。
感谢您的帮助,我可能会得到。
头文件:
#ifndef MYCLASS_HPP
#define MYCLASS_HPP
#include <memory>
#include <boost/asio.hpp>
class MyClass
{
public:
MyClass(boost::asio::io_service& ios);
void read();
void read_handler(const boost::system::error_code& error);
static std::shared_ptr<MyClass> create(std:: string const & host, uint16_t port);
bool connect (std::string const & host, uint16_t port);
void connect_handler(const boost::system::error_code& error);
boost::asio::ip::tcp::socket m_socket;
bool m_flag;
std::vector<uint8_t> m_buffer;
};
#endif
源文件:
#include "MyClass.hpp"
#include <boost/bind.hpp>
MyClass::MyClass(boost::asio::io_service& ios)
:m_flag(false), m_socket(ios), m_buffer(20)
{
}
void MyClass::read_handler(const boost::system::error_code& er)
{
std::cout << "Timer waited 5 sec" << std::endl;
}
void MyClass::read()
{
boost::asio::deadline_timer t(m_socket.get_io_service(),boost::posix_time::seconds(5));
t.async_wait(boost::bind(&MyClass::read_handler,this,boost::asio::placeholders::error));
m_socket.get_io_service().run();//Should make the io_service wait for all asynchronous tasks to finish
std::cout << "This message should be displayed after the wait" << std::endl;
}
void MyClass::connect_handler(const boost::system::error_code& error)
{
if(!error)
{
std::cout << "Connection done" << std::endl;
m_flag = 1;
}
else
{
std::cout << "Error in connection: " << error.message() << std::endl;
}
}
//connect method
bool MyClass::connect(std::string const & host, uint16_t port)
{
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::address::from_string(host),port);
m_socket.async_connect(endpoint,
boost::bind(&MyClass::connect_handler, this,
boost::asio::placeholders::error));
m_socket.get_io_service().run();//Wait async_connect and connect_handler to finish
if (m_flag == 0) return false;
else return true;
}
std::shared_ptr<MyClass> MyClass::create(std:: string const & host, uint16_t port)
{
boost::asio::io_service ios;
std::shared_ptr<MyClass> ptr(new MyClass(ios));
bool bol = ptr->connect(host, port);
ptr->read();
//while(1){}
if(bol == true)
{
//connection success, reading currently listening, pointer is returned to the user
return ptr;
}
else
{
//connection failure, pointer is still returned to the user but not listening as he's not connected
return ptr;
}
}
我的主:
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/asio.hpp>
#include "MyClass.hpp"
int main()
{
try
{
std::cout << "Creation of instance" << std::endl;
std::shared_ptr <MyClass> var = MyClass::create("127.0.0.1", 8301);
std::cout << "Instance created" << std::endl;
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
由于您正在'MyClass :: create'中创建一个临时的'boost :: asio :: io_service',在你可以调用'run'或'poll'之前它被销毁了。尝试在'main'中创建它,然后将它传递给'MyClass :: create',然后调用'run()'。 – kenba
@kenba显然你是对的,但我也忘了我的io_service重置(),我会尽量让他活着 – PsykoBabar
@PsykoBabar是你在'read()'中再次调用'io_service :: run'的意图' ?为了保持'io_service'活着,请按照@kenba的建议,但是也可以从'connect_handler'调用'read()'。这样'read()'在连接成功之后被调用。现在,无论是否存在连接,都会调用read()。我知道这可能是调试代码,并且你不是从'read()'中的套接字读取的,但是你绝对不需要'重置''io_service'并再次调用'run'。 – aichao