Boost Asio Windows \u流\u处理程序-异步\u读取\u某些未递归调用

Boost Asio Windows \u流\u处理程序-异步\u读取\u某些未递归调用,boost,boost-asio,Boost,Boost Asio,我使用boost::asio::windows::stream\u句柄并使用async\u read\u某种方法从命名管道递归读取数据。我将一个read\u处理程序与async\u read\u some方法相关联。但是async_read_某些处理程序只被调用一次,当新消息通过管道时,它不会被进一步调用。使用试错法,我再次将read_处理程序分配给async_read_some方法,现在可以正确地调用它。但这是正确的做法,还是请建议一种优雅的方式,从管道中获得持续的响应 boost::asio

我使用boost::asio::windows::stream\u句柄并使用async\u read\u某种方法从命名管道递归读取数据。我将一个read\u处理程序与async\u read\u some方法相关联。但是async_read_某些处理程序只被调用一次,当新消息通过管道时,它不会被进一步调用。使用试错法,我再次将read_处理程序分配给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));
}
boost::asio::io\u服务我的io\u服务;
boost::asio::windows::stream\u handle管道(我的io服务);
boost::数组缓冲区;
void CPublishSubscribeLib::read_处理程序(常量boost::system::error_code&ec,std::size_t bytes_transfer)
{
如果(传输的字节数>0)
异步读取(boost::asio::buffer(buffer,150),boost::bind(&cpublishssubscribelib::read_handler,this,_1,_2));
}

感谢是前进

在回答您关于从管道获取连续数据流的正确方法的问题时,可以从自身调用read_处理程序来处理下一条消息。我在我的代码中这样做,它工作得很好。需要记住的重要一点是,read_处理程序所在的线程需要负责。这意味着处理每条消息不应该花费太多时间。因此,许多人建议只需将消息复制到缓冲区,然后将其存储在保存消息的某种容器(队列、堆栈或向量)中,然后通知工作线程唤醒并处理消息。这是我在代码中采用的方法。但是,如果处理量很小和/或服务器发送的消息不多,则可能不需要在代码中这样做。如果在将小消息从套接字复制到缓冲区时关注性能和内存碎片,那么您可能会考虑分配一个大的环绕缓冲区来存储消息。在每条消息到达堆外时为其分配空间。

对于Boost.Asio,单个异步操作只能调用关联的处理程序一次,然后立即删除处理程序Boost.Asio创建的所有副本。因此,如果一个
async\u read\u some
操作只启动一次,那么ReadHandler将只调用一次。通过从同一操作的处理程序中启动操作来形成异步链是一种非常常见的模式。在这种情况下,从
cppublishsubscribelib::read\u handler

中启动
async\u read\u some
操作是正常的,要么
read\u handler
使用
bytes\u transfer==0
调用,要么
my\u io\u service::run
退出。