3

几周以来,我一直致力于将 ENet 封装成一组易于使用的函数,但似乎有点问题。

我有一个 std::stringstream 并尝试使用 ENet 将内容发送到远程机器,然后在远程机器上重建 std::stringstream。

我需要使用 std::stringstream 的原因是因为我正在使用需要流的 Cereal Serialization Library 序列化我的数据。

在 Azoth 的帮助下,他确定我需要使用 std::istringstream 和 std::ostringstream。以前我只使用导致异常的 std::stringstream 。

然而,现在在便携式_binary.hpp 第 156 行的 Cereal 中引发了一个异常:

throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize));

这就是我正在做的事情:

void Send(ENetHost* Host)
{
    std::ostringstream SData;
    {
        cereal::PortableBinaryOutputArchive Archive(SData);
        Archive(PacketData);
    }

    std::string Out = SData.str();

    ENetPacket* Packet = enet_packet_create(Out.c_str(), Out.size(), ENET_PACKET_FLAG_RELIABLE);
    enet_host_broadcast(Host, 0, Packet);
}

谷物便携式二进制数据存档被构造为保存单个向量。使用 ENet 将 std::ostringstream 发送到主机。

这部分似乎工作正常,我可以打印前后的信息,看起来是一样的,虽然有一些奇怪的符号,但它们在两端打印出来的都是一样的。

现在使用我们收到的数据在主机上创建一个 std::istringstream。

NetPacket(enet_uint8 const* Data)
{
    std::istringstream SData(reinterpret_cast<char const*>(Data));
    {
        cereal::PortableBinaryInputArchive Archive(SData);
        Archive(PacketData);
    }
}

此时我在行收到异常:

Archive(PacketData)

我感觉数据在通过 ENet 发送时正在以某种方式发生变化和/或我没有正确地将数据从 std::ostringstream 中提取出来和/或没有正确地将数据放回 std::istringstream 中。

非常感谢您的宝贵时间,我非常感谢。

4

1 回答 1

3

免责声明:我不熟悉enet。

您收到此错误是因为您std::stringstream在收到数据包时没有正确构建。发送/接收对应如下所示:

my_send_function()
{
  std::ostringstream os;
  {    
    cereal::PortableBinaryOutputArchive ar(os);
    ar( whatever_needs_to_be_serialized );
  } // the binary archives will flush their output 
    // immediately, but it's better to
    // use cereal archives in an RAII matter all the time

  std::string data = os.str();

  create_packet(data.c_str(), data.size());
  // send out
}

然后在接收端,是这样的:

my_receive_function( uint8_t const * data ) // data came from some packet
{
  MyDataType d;

  std::istringstream is(reinterpet_cast<char const *>(data));
  // this is safe to do since we generated the data using c_str(), which added
  // a null terminator to the data
  {
    cereal::PortableBinaryInputArchive ar(is);
    ar( d );
  }
}

这里的基本思想:使用谷物和一些 ostringstream 生成一个字符串(实际上只是一个字节数组),通过网络发送这些原始字节,将它们拉入 istringstream,然后让谷物解析它。

于 2014-04-05T05:57:44.820 回答