对于作为 的缓冲区参数传递的对象async_read()
,缓冲区参数要么:
因此,可以编写一个Sink
在读取发生时与对象交互的自定义类。但是,boost::asio::basic_streambuf
似乎并没有被设计为用作基类。
如果Sink::write
只是对底层内存的抽象,请考虑使用类似于 的方法basic_streambuf::prepare()
,其中成员函数返回给定大小的缓冲区的句柄。底层内存实现仍将在mutable_buffer
. 例如:
boost::asio::async_read( socket, sink.buffer( size ), ... );
如果Sink::write
有业务逻辑,比如根据某些字节的值进行逻辑分支,那么可能需要传递一个中间缓冲区给async_read()
. Sink::write()
然后将在async_read()
的处理程序中完成对中间缓冲区的调用。例如:
void handle_read_into_sink( boost::system::error_code error,
std::size_t bytes_transferred,
boost::asio::ip::tcp::socket& socket,
Sink& sink,
char* buffer,
std::size_t buffer_size,
std::size_t bytes_remaining,
boost::function< void() > on_finish )
{
sink.write( buffer, buffer_size );
bytes_remaining -= bytes_transferred;
// If there are more bytes remaining, then continue reading.
if ( bytes_remaining )
{
read_into_sink( socket, sink, buffer, buffer_size,
bytes_remaining, on_finish );
}
// Otherwise, all data has been read.
else
{
on_finish();
}
}
void read_into_sink( boost::asio::ip::tcp::socket& socket,
Sink& sink,
char* buffer,
std::size_t buffer_size,
std::size_t bytes_remaining,
boost::function< void() > on_finish )
{
boost::asio::async_read(
socket, boost::asio::buffer( buffer , buffer_size ),
boost::asio::transfer_exactly( buffer_size ),
boost::bind( handle_read_into_sink,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred,
boost::ref( socket ),
boost::ref( sink ),
buffer,
buffer_size,
bytes_remaining,
on_finish ) );
}
并开始异步读取循环:
read_into_sink( socket, sink, small_buffer, sizeof_small_buffer,
total_stream_size, read_handler_callback );
确保根据您所需的逻辑检查和处理错误。