私は最近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;
}
一時的な 'boost :: asio :: io_service'を' Run'や 'poll'を呼び出す前に破壊される' MyClass :: create'に作成しています。それを 'main'で作成し、' MyClass :: create'に渡してから 'run()'を呼び出してみてください。 – kenba
@kenba明らかにあなたは正しいと思っていましたが、io_serviceのreset()も忘れてしまいました。私は彼を生かしておきます。 – PsykoBabar
@PsykoBabarは、 'read()'で 'io_service :: run'を再度呼び出すことを意図しています。 ? 'io_service'を生かしたままにするには、@kenbaが示唆していることを実行するだけでなく、' connect_handler'から 'read()'を呼び出します。接続が成功した後、 'read()'が呼び出されます。今、 'read()'は、接続があるかどうかを呼び出す。私はこれがおそらくデバッグコードであり、 'read()'でソケットから読み込んでいないことを知っていますが、 'io_service'を'リセット 'して再度 'run'を呼び出す必要はありません。 – aichao