使用boost :: asio :: windows :: stream_handle并使用async_read_some方法递归地从命名管道中读取数据。我将read_handler与async_read_some方法关联起来。但async_read_some处理程序只被调用一次,当新消息通过管道时,它不会被进一步调用。使用试错法,我再次将read_handler分配给async_read_some方法,现在可以正确调用它。但这是正确的做法还是请建议一种从管道中获得持续响应的优雅方式。
boost::asio::io_service my_io_service;
boost::asio::windows::stream_handle pipe( my_io_service);
boost::array<char, 4096> buffer;
void CPublishSubscribeLib::read_handler(const boost::system::error_code& ec, std::size_t bytes_transferred)
{
if(bytes_transferred > 0 )
pipe.async_read_some(boost::asio::buffer(buffer, 150), boost::bind(&CPublishSubscribeLib::read_handler, this, _1, _2));
}
谢谢你提前!
答案 0 :(得分:1)
使用Boost.Asio,单个异步操作只能调用一次关联的处理程序,然后立即删除Boost.Asio创建的处理程序的所有副本。因此,如果async_read_some
操作仅启动一次,则 ReadHandler 将仅调用一次。通过从同一操作的处理程序内启动操作来形成异步链是一种非常常见的模式。在这种情况下,从async_read_some
内发起CPublishSubscribeLib::read_handler
操作是正常的。
答案 1 :(得分:0)
在回答有关从管道获取连续数据流的正确方法的问题时,可以从内部调用read_handler来处理下一条消息。我在我的代码中这样做,它工作正常。要记住的重要一点是,read_handler所在的线程需要重新使用。这意味着它不应该花费太多时间来处理每条消息。因此,许多人建议只是将消息复制到缓冲区,然后将其存储在保存消息的某种容器(队列,堆栈或向量)中,然后通知工作线程唤醒并处理消息。这是我在代码中采用的方法。但是,如果处理很少和/或服务器不发送许多消息,您可能不需要在代码中执行此操作。如果在从套接字将小消息复制到缓冲区时担心性能和内存碎片,那么您可以考虑分配一个大的环绕缓冲区来存储消息.vs。为每条消息从堆中到达时分配空间。