我最近遇到了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