我有一个序列化的结构,通过套接字发送.我需要以块的形式读取它,因为它的一个字段包含剩余数据的大小:我需要读取前几个字节,找出长度并阅读其余部分.这就是我所拥有的:
boost::asio::streambuf buffer; boost::system::error_code err_code; // here I need to read only first 16 bytes boost::asio::read(socket,buffer,err_code); std::istream is(&buffer); boost::archive::binary_iarchive ia(is); ia >> my_struct;@H_403_3@我看了看
boost::asio::async_read(s,boost::asio::buffer(data,size),handler);@H_403_3@但它只能读取数据到boost :: asio :: buffer.我想知道我是否可以使用boost :: asio :: streambuf做同样的事情?先感谢您.
解决方法
@L_403_0@和
boost::asio::async_read()
都有重载接受
boost::asio::basic_streambuf
的实例作为其缓冲区:
read(SyncReadStream&,basic_streambuf&); read(SyncReadStream&,basic_streambuf&,CompletionCondition); read(SyncReadStream&,boost::system::error_code&); read(SyncReadStream&,CompletionCondition,boost::system::error_code&); async_read(AsyncReadStream&,ReadHandler); async_read(AsyncReadStream&,ReadHandler);@H_403_3@当调用不接受CompletionCondition的重载时,它相当于使用CompletionCondition
boost::asio::transfer_all()
调用其关联的重载,导致操作读取streambuf.max_size()
个字节.要将已知数量的字节读入streambuf,请使用:
>
boost::asio::transfer_exactly(n)
CompletionCondition限制从组合操作传输的字节数:std::size_t n = // ... boost::asio::read(socket,streambuf,boost::asio::transfer_exactly(n),error);@H_403_3@>显式创建一个将用作缓冲区的输出序列,然后将读取的字节提交到streambuf的输入序列:
std::size_t n = // ... std::size_t bytes_transferred = boost::asio::read(socket,streambuf.prepare(n),// creates a boost::asio::buffer error); streambuf.commit(bytes_transferred);@H_403_3@以下是这些方法的完整示例demonstrating:
#include <iostream> #include <boost/asio.hpp> #include <boost/bind.hpp> // This example is not interested in the handlers,so provide a noop function // that will be passed to bind to meet the handler concept requirements. void noop() {} std::string make_string(boost::asio::streambuf& streambuf) { return {boost::asio::buffers_begin(streambuf.data()),boost::asio::buffers_end(streambuf.data())}; } int main() { using boost::asio::ip::tcp; boost::asio::io_service io_service; // Create all I/O objects. tcp::acceptor acceptor(io_service,tcp::endpoint(tcp::v4(),0)); tcp::socket server_socket(io_service); tcp::socket client_socket(io_service); // Connect client and server sockets. acceptor.async_accept(server_socket,boost::bind(&noop)); client_socket.async_connect(acceptor.local_endpoint(),boost::bind(&noop)); io_service.run(); // Write to server. boost::asio::streambuf write_buffer; std::ostream output(&write_buffer); output << "abc"; std::cout << "Writing: " << make_string(write_buffer) << std::endl; auto bytes_transferred = boost::asio::write(server_socket,write_buffer); // Read from client. boost::asio::streambuf read_buffer; bytes_transferred = boost::asio::read(client_socket,read_buffer,boost::asio::transfer_exactly(bytes_transferred)); std::cout << "Read: " << make_string(read_buffer) << std::endl; read_buffer.consume(bytes_transferred); // Remove data that was read. // Write to server. output << "def"; std::cout << "Writing: " << make_string(write_buffer) << std::endl; bytes_transferred = boost::asio::write(server_socket,write_buffer); // Read from client. bytes_transferred = boost::asio::read(client_socket,read_buffer.prepare(bytes_transferred)); read_buffer.commit(bytes_transferred); std::cout << "Read: " << make_string(read_buffer) << std::endl; read_buffer.consume(bytes_transferred); // Remove data that was read. }@H_403_3@输出:
Writing: abc Read: abc Writing: def Read: def@H_403_3@