C++ Boost Asio-为什么我的异步操作不启动?

C++ Boost Asio-为什么我的异步操作不启动?,c++,c++11,boost,boost-asio,shared-ptr,C++,C++11,Boost,Boost Asio,Shared Ptr,我最近在boost::asio异步任务中遇到了一个问题。我想返回监听端口的对象上的指针。 当我使用socket.read_some方法时,它可以工作,但是这个方法阻塞了我的main,我希望我的MyClass::create方法返回 所以我尝试了一个async_read调用,但我发现在我的read()方法中,没有启动任何异步任务。我试图找出问题的原因,但没有找到解决这个问题的办法 这是我的代码,这里不是异步读取,而是异步等待,同样的问题出现了,计时器没有启动 谢谢你给我的任何帮助 头文件: #if

我最近在boost::asio异步任务中遇到了一个问题。我想返回监听端口的对象上的指针。 当我使用socket.read_some方法时,它可以工作,但是这个方法阻塞了我的main,我希望我的MyClass::create方法返回

所以我尝试了一个async_read调用,但我发现在我的read()方法中,没有启动任何异步任务。我试图找出问题的原因,但没有找到解决这个问题的办法

这是我的代码,这里不是异步读取,而是异步等待,同样的问题出现了,计时器没有启动

谢谢你给我的任何帮助

头文件:

#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
#如果我的等级为水电站
#定义MYCLASS_水电站
#包括
#包括
类MyClass
{
公众:
MyClass(boost::asio::io_服务和ios);
无效读取();
无效读取处理程序(常量boost::system::error\u代码和错误);
静态std::shared_ptr create(std::string const&host,uint16_t port);
布尔连接(标准::字符串常量和主机,uint16_t端口);
无效连接处理程序(const boost::system::error\u代码和错误);
boost::asio::ip::tcp::socket m_socket;
布尔穆旗;
std::向量m_缓冲区;
};
#恩迪夫
源文件:

#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;
    }
}
#包括“MyClass.hpp”
#包括
MyClass::MyClass(boost::asio::io_服务和ios)
:m_标志(假)、m_插槽(ios)、m_缓冲区(20)
{   
}
void MyClass::read\u处理程序(const boost::system::error\u code&er)
{

我想出了解决问题的办法

在“create”方法之后,我确实遇到了io_服务被销毁的问题,因此在main中返回的指针无法继续读取。 我必须在某一时刻调用run()来启动回调,但我无法在main中执行此操作,因为我希望main继续执行其他操作

因此,我创建了一个类,该类启动一个单独的线程并包含一个io_服务。该线程定期调用run(),然后将其作为属性添加到MyClass中


现在我可以调用“create”,返回指向MyClass的指针,MyClass不会停止MyClass中启动的任何异步任务。

我找到了解决问题的方法

在“create”方法之后,我确实遇到了io_服务被销毁的问题,因此在main中返回的指针无法继续读取。 我必须在某一时刻调用run()来启动回调,但我无法在main中执行此操作,因为我希望main继续执行其他操作

因此,我创建了一个类,该类启动一个单独的线程并包含一个io_服务。该线程定期调用run(),然后将其作为属性添加到MyClass中


现在我需要“创建”返回指向MyClass的指针,该指针不会停止MyClass中启动的任何异步任务。

因为您正在
MyClass::create
中创建一个临时
boost::asio::io_服务
,该服务在调用
run
poll
之前被销毁。请尝试在
main
中创建它,并将其传递给de>MyClass::create
并在其上调用
run()
。@kenba显然你是对的,但我也忘记了io_服务上的重置(),我会尽力留住他alive@PsykoBabar您是否打算在
read()中再次调用
io\u service::run
?要保持
io\u服务
处于活动状态,请按照@kenba的建议执行操作,但也要从
connect\u处理程序
调用
read()
。这样,在连接成功后会调用
read()
。现在,
read()无论是否存在连接,都会调用
。我知道这可能是调试代码,并且您没有在
read()
中从套接字读取,但您肯定不需要
重置
io_服务
并再次调用
运行
。不,我不想调用io_服务::在read()中运行最后,我的目标是在main中调用MyClass::create之后保持async_read()的活动状态(在main中没有io_服务).不幸的是,@kenba所说的是真的,我必须找到另一种方法来维持我的io_服务。我会在他整理文档时将此主题标记为已解决issue@PsykoBabar,@aichao也是正确的。
io_service.run()
需要一些工作来阻止它完成。你的
MyClass::connect\u处理程序应该执行一个异步操作:写入、读取等,以保持它的活动状态,因为你正在
MyClass::create
中创建一个临时
boost::asio::io\u服务,它在调用
run
poll之前就被销毁了
在上面。试着在
main
中创建它,将它传递给
MyClass::create
,然后调用
run()
。@kenba显然你是对的,但我也忘了在io_服务上重置(),我会尽力留住他alive@PsykoBabar您是否打算在
read()中再次调用
io\u service::run
?要保持
io\u服务
处于活动状态,请按照@kenba的建议执行操作,但也要从
connect\u处理程序
调用
read()
。这样,在连接成功后会调用
read()
。现在,
read()无论是否存在连接,都会调用
。我知道这可能是调试代码,并且您没有在
read()
中从套接字读取,但您肯定不需要
重置
io_服务
并再次调用
运行
。不,我不想调用io_服务::在read()中运行最后,我的目标是在main中调用MyClass::create之后保持async_read()的活动状态(在main中没有io_服务).不幸的是,@kenba所说的是真的,我必须找到另一种方法来维持我的io_服务。我会在他整理文档时将此主题标记为已解决issue@PsykoBabar,@aichao也是正确的。
io_service.run()
需要一些工作来阻止它完成。您的
MyClass::connect\u处理程序应该执行异步操作:写入、读取等,以保持
#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;
}