Boost ASIO:异步写入,同步

Sam*_*kus 6 c++ boost asynchronous boost-asio c++11

我有一个程序(客户端 + 服务器),可以正常使用此写入:

boost::asio::write(this->socket_, boost::asio::buffer(message.substr(count,length_to_send)));
Run Code Online (Sandbox Code Playgroud)

哪里socket_boost::asio::ssl::stream<boost::asio::ip::tcp::socket>并且messagestd::string

我想让它变得更好和非阻塞,所以我创建了一个可以替换它的函数,它的调用方式如下:

write_async_sync(socket_,message.substr(count,length_to_send));
Run Code Online (Sandbox Code Playgroud)

这个函数的目的是:

  1. 为了使调用异步,本质上
  2. 保持界面不变

我实现的函数只是使用 promise/future 来模拟同步行为,我稍后(在它工作后)将修改为可取消:

std::size_t 
SSLClient::write_async_sync(boost::asio::ssl::stream<boost::asio::ip::tcp::socket>& socket, 
                            const std::string& message_to_send)
{
    boost::system::error_code write_error;
    std::promise<std::size_t> write_promise;
    auto write_future = write_promise.get_future();

    boost::asio::async_write(socket,
                             boost::asio::buffer(message_to_send), 
        [this,&write_promise,&write_error,&message_to_send]
        (const boost::system::error_code& error,
        std::size_t size_written)
        {
            logger.write("HANDLING WRITING");
            if(!error)
            {
                write_error = error;
                write_promise.set_value(size_written);
            }
            else
            {
                write_promise.set_exception(std::make_exception_ptr(std::runtime_error(error.message())));
            }
        });
    std::size_t size_written = write_future.get();
    return size_written;
}
Run Code Online (Sandbox Code Playgroud)

问题:我无法使用异步功能。sync 工作正常,但 async 只是冻结并且永远不会进入 lambda 部分(写入永远不会发生)。我究竟做错了什么?


编辑:我意识到 usingpoll_one()使函数执行并继续,但我不明白。这是我如何打电话run()io_service(在启动客户端前):

io_service_work = std::make_shared<boost::asio::io_service::work>(io_service);
io_service_thread.reset(new std::thread([this](){io_service.run();}));
Run Code Online (Sandbox Code Playgroud)

基本上这些在哪里shared_ptr。这是错误的吗?这种方式是否需要使用poll_one()

seh*_*ehe 2

关于。编辑:

你有io_service::run()正确的。这告诉我您正在(完成)处理程序中阻止未来。显然,这会阻止run()事件循环的进行。


@florgeng 提出的问题不是你是否有io_service实例。

问题是您是否适当地调用run()(或poll()) 来进行异步操作。

此外,您已经可以使用future<>内置的:

std::future<std::size_t> recv_length = socket.async_receive_from(
      boost::asio::buffer(recv_buf),
      sender_endpoint,
      boost::asio::use_future);
Run Code Online (Sandbox Code Playgroud)