使用boost.asio的免费async_ *函数时出现奇怪的错误

时间:2013-07-12 13:02:24

标签: c++ boost boost-asio

我在我正在编写的应用程序中获得了此代码段:

#include "ClientSession.hpp"
void ClientSession::start(void)
{
    auto Self(shared_from_this());

    //boost::asio::read(this->_Socket, boost::asio::buffer(this->_ReadBuffer));

    //this->_Socket.get_io_service().post(boost::bind(&ClientSession::on_read, shared_from_this(), boost::system::error_code::error_code(), 0));

    boost::asio::async_read(this->_Socket, boost::asio::buffer(this->_ReadBuffer), boost::bind(&ClientSession::on_read, Self, _1, _2));
}

void ClientSession::on_read(const boost::system::error_code& Err_, size_t Bytes_)
{
    try 
    {
        if(Err_)
        {
            if(!(Err_ == boost::asio::error::eof || Err_ == boost::asio::error::connection_aborted))
            {
                throw std::runtime_error(Err_.message());
            }
            return;
        }

    }
    catch(std::exception& Ex_)
    {
        this->_OutputHandler.write_error(Ex_.what());
    }
}

调用ClientSession :: start的代码是:

void Application::start_accept()
{

    using namespace boost::asio;
    ip::tcp::endpoint Endpoint( ip::address::from_string(this->_Config.get_client_login_server().first), this->_Config.get_client_login_server().second );
    this->_ClientAcceptor.open(Endpoint.protocol());
    this->_ClientAcceptor.bind(Endpoint);
    this->_ClientAcceptor.listen();

    std::shared_ptr<ClientSession> Session = ClientSession::create_new(this->_AsioService, this->_OutputHandler);
    this->_ClientAcceptor.async_accept(Session->get_socket(), boost::bind(&Application::handle_accept, shared_from_this(), Session, _1));

}

如果我使用其中一条注释掉的行运行应用程序它就可以正常工作(在boost :: asio :: read版本中,来自客户端的传输消息被写入读取缓冲区并且在后期版本中处理器函数被调用没有任何问题),但如果尝试使用我的应用程序与async_read部分我的整个应用程序总是崩溃,而不调用完整的句柄或甚至读取一个字节!,至少它看起来像输出asio给我:

  

@asio | 1373633560.834957 | 0 * 1 | socket@000000BD603D46C0.async_accept     @asio | 1373633573.324144 |→1个| EX =系统:0     @asio | 1373633573.324144 | 1 * 2 | socket@000000BD603DBAB8.async_receive

我将它重命名为一个名为“select_reactor.ipp”的文件,其中应用程序试图获取一个boost :: asio :: detail :: mutex :: scoped_lock,它看起来像是在那里失败了,完整的代码是方法是:

void select_reactor::start_op(int op_type, socket_type descriptor,
select_reactor::per_descriptor_data&, reactor_op* op,
bool is_continuation, bool)
{
  boost::asio::detail::mutex::scoped_lock lock(mutex_);

  if (shutdown_)
  {
    post_immediate_completion(op, is_continuation);
    return;
  }

  bool first = op_queue_[op_type].enqueue_operation(descriptor, op);
  io_service_.work_started();
  if (first)
    interrupter_.interrupt();
}

我不知道也许我正在做一些非常错误的事情,但我不知道是什么,我希望有人可以给我一个提示,我可以做些什么来解决这个错误。

根据我到目前为止的评论,我将添加更多完整的代码段: 我的io_service在我的Application类中:

class Application
    : public std::enable_shared_from_this<Application>
{
typedef boost::asio::io_service Service;
typedef boost::asio::ip::tcp::acceptor Acceptor;

public:
    Application(void) 
        : _ClientAcceptor(_AsioService), _ApplicationRunning(true)
    {
    }

    ~Application(void);

    /*
     * This is the main method which starts the actual program routine
     * called in main()
     */
    int run(void);

private:
    /*
     * Invokes the first accept and then invokes via async. handle_accept, which invokes itself repeatedly
     */
    void start_accept(void);
    /*
     * handle_accept calls NewClient_->start to invoke the communication with this client 
     */
    void handle_accept(std::shared_ptr<ClientSession> NewClient_, const boost::system::error_code& Err_);

    void loop_for_user_input(void);
    bool handle_user_input(const std::string& Msg_);

    /*
     * This method invokes the threads that call io_service::run()
     */
    static void start_service(Service& AsioService_) { try { AsioService_.run(); } catch(const std::exception& Ex_) { std::cout << Ex_.what() << std::endl; } }

private:
    Configuration _Config;
    Service _AsioService;
    Acceptor _ClientAcceptor;
    OutputHandler _OutputHandler;

    bool _ApplicationRunning;
};

和run方法:

int Application::run(void)
{
    try 
    {
        this->_Config.load();
        this->_OutputHandler.open(this->_Config.get_logs());

        this->start_accept();

        for(int i = 0; i < 4; i++)
        {
            std::thread t(start_service, std::ref(this->_AsioService));
            t.detach();
        }

        this->loop_for_user_input();

    }
    catch(const std::runtime_error& Ex_)
    {
        this->_OutputHandler.write_error(Ex_.what());
    }

    return 0;
}

1 个答案:

答案 0 :(得分:1)

我发现了错误,这只是我的_WIN32_WINNT预处理程序指令设置中的一个错字,即_WIN32_WINNT 0x0601(对于Windows 7)解决了这个问题。