是否可以使用boost :: asio一次性发送几种不同的数据类型而不进行转换?

时间:2011-04-26 02:18:38

标签: boost boost-asio

目前我正在使用我的所有数据填充std :: vector,然后使用async_write发送它。我发送的所有数据包都有一个2字节的标头,这告诉接收器要读取多少(如果有的话)。生成此std :: vector的代码是:

std::vector<boost::asio::const_buffer> BasePacket::buffer()
{
  std::vector<boost::asio::const_buffer> buffers;
  buffers.push_back(boost::asio::buffer(headerBytes_)); // This is just a boost::array<uint8_t, 2>
  return buffers;
}

std::vector<boost::asio::const_buffer> UpdatePacket::buffer()
{
  printf("Making an update packet into a buffer.\n");
  std::vector<boost::asio::const_buffer> buffers = BasePacket::buffer();
  boost::array<uint16_t, 2> test = { 30, 40 };
  buffers.push_back(boost::asio::buffer(test));
  return buffers;
}

这可以通过以下方式阅读:

void readHeader(const boost::system::error_code& error, size_t bytesTransferred)
{
  if(error)
  {
    printf("Error reading header: %s\n", error.message().c_str());
    return;
  }

  // At this point 2 bytes have been read into boost::array<uint8_t, 2> header
  uint8_t primeByte = header.data()[0];
  uint8_t supByte = header.data()[1];

  switch(primeByte)
  {
    // Unrelated case removed
    case PACKETHEADER::UPDATE:
      // Read the first 4 bytes as two 16-bit numbers representing the size of
      // the update
      boost::array<uint16_t, 2> buf;
      printf("Attempting to read the first two Uint16's.\n");
      boost::asio::read(mySocket, boost::asio::buffer(buf));
      printf("The update has size %d x %d\n", buf.data()[0], buf.data()[1]);
      break;
  }

  // Keep listening
  boost::asio::async_read(mySocket, boost::asio::buffer(header),
    boost::bind(readHeader, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

代码编译,但它没有像我期望的那样返回30 x 40。相反,它返回 188 x 40.如果我拉伸第二个数组,只有第一个字节搞砸了。但是,如果我在发送之前添加第三个数组(但仍然读取发送量),则第二个数组的值全部搞砸了。我猜这可能与我如何阅读它有关(在一个缓冲区中,而不是类似于我写它的方式)。

理想情况下,我希望避免将所有内容转换为字节并以这种方式读/写,因为它不太清晰,可能不太便携,但我知道这是一个选项。但是,如果有更好的方法,我可以很好地改写我所拥有的。

1 个答案:

答案 0 :(得分:1)

我看到的第一个问题是您发送的数据的终身问题。 asio :: buffers只是包装你继续拥有的数据缓冲区。

UpdatePacket :: buffer()方法创建一个boost :: array,它包装然后再推回缓冲区std :: vector。当方法退出时,boost :: array超出范围,而asio :: buffer现在指向garbage。

可能还有其他问题,但这是一个好的开始。请注意Asio中数据缓冲区的生命周期。