Boost ASIO:异步写入,同步

时间:2017-05-19 18:15:24

标签: c++ c++11 asynchronous boost boost-asio

我有一个程序(客户端+服务器),该程序没有问题:

boost::asio::write(this->socket_, boost::asio::buffer(message.substr(count,length_to_send)));

其中socket_boost::asio::ssl::stream<boost::asio::ip::tcp::socket>messagestd::string

我想让这个更好,更无阻塞,所以我创建了一个可以替换它的函数,它被称为如下:

write_async_sync(socket_,message.substr(count,length_to_send));

此功能的目的是:

  1. 使调用异步,本质上
  2. 保持界面不变
  3. 我实现的函数只是使用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;
    }
    

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

    编辑:我意识到使用poll_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();}));
    

    其中基本上是shared_ptr。这是错的吗?这种方式是否需要使用poll_one()

1 个答案:

答案 0 :(得分:1)

重新。编辑:

您正确拥有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);