开发者

Is it possible to send several different datatypes at once with boost::asio without casting?

At the moment I'm filling an std::vector with all of my data and then sending it with async_write. All of the packets I send have a 2 byte header and this tells receiver how much further to read (if any further at all). The code which generates this std::vector is:

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;
}

This is read by:

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));
}

The code compiles, however it doesn't return 30 x 40 as I would expect. Instead it returns 188 x 40. If I stretch the second array out only the first byte is messed up. However, if I add a third array before sending (but still read the send amount), the values of the second array all get messed up. I'm guessing that this could be related to how I'm reading it (in chunks into one buffer rather than similar to how I'm writing it).

Ideally I'd like to avoid having to cast everything into bytes and read/write that way, since it's less clear and probably less port开发者_如何学运维able, but I know that's an option. However, if there is a better way I'm fine rewriting what I have.


The first problem I see is a lifetime issue with the data you are sending. asio::buffers simply wrap a data buffer that you continue to own.

The UpdatePacket::buffer() method creates a boost::array which it wraps and then pushes back on the buffers std::vector. When the method exits the boost::array goes out of scope and the asio::buffer is now pointing to garbage.

There maybe other issues, but this is a good start. Mind the lifetimes of your data buffers in Asio.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜