Можно ли отправить несколько разных типов данных одновременно с boost :: asio без приведения? - PullRequest
0 голосов
/ 26 апреля 2011

В данный момент я заполняю 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 Ответ

1 голос
/ 27 апреля 2011

Первая проблема, которую я вижу, - это пожизненная проблема с данными, которые вы отправляете.asio :: buffers просто оборачивают буфер данных, которым вы продолжаете владеть.

Метод UpdatePacket :: buffer () создает массив boost ::, который он оборачивает, а затем возвращает буферы std :: vector.Когда метод завершает работу, boost :: array выходит из области видимости, и asio :: buffer теперь указывает на мусор.

Возможно, есть другие проблемы, но это хорошее начало.Учитывайте время жизни ваших буферов данных в Asio.

...