微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – boost :: asio读取从socket到streambuf的n个字节

我有一个序列化的结构,通过套接字发送.我需要以块的形式读取它,因为它的一个字段包含剩余数据的大小:我需要读取前几个字节,找出长度并阅读其余部分.这就是我所拥有的:
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;

我看了看

boost::asio::async_read(s,boost::asio::buffer(data,size),handler);

但它只能读取数据到boost :: asio :: buffer.我想知道我是否可以使用boost :: asio :: streambuf做同样的事情?先感谢您.

解决方法

boost::asio::read()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);

调用不接受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);

>显式创建一个将用作缓冲区的输出序列,然后将读取的字节提交到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);

以下是这些方法的完整示例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.
}

输出

Writing: abc
Read: abc
Writing: def
Read: def

原文地址:https://www.jb51.cc/c/117491.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐