简体   繁体   English

使用ENet从Cereal发送二进制数据的StringStream

[英]Sending a StringStream of Binary Data from Cereal with ENet

I have been working on wrapping ENet into a set of easy to use functions for a few weeks now and seem to have a bit of an issue. 我一直在努力将ENet包装成一组易于使用的功能,持续几周,似乎有一些问题。

I have a std::stringstream and am attempting to send the contents to a remote machine using ENet then reconstruct the std::stringstream on the remote machine. 我有一个std :: stringstream,我正在尝试使用ENet将内容发送到远程计算机,然后在远程计算机上重建std :: stringstream。

The reason I need to use a std::stringstream is due to the fact that I'm serializing my data with the Cereal Serialization Library which requires a stream. 我需要使用std :: stringstream的原因是因为我正在使用需要流的Cereal Serialization Library来序列化我的数据。

With Azoth's help he has identified that I need to be using std::istringstream and std::ostringstream. 在Azoth的帮助下,他发现我需要使用std :: istringstream和std :: ostringstream。 Previously I was only using std::stringstream which was causing an exception. 以前我只使用std :: stringstream导致异常。

However now an exception is being thrown within Cereal at portable_binary.hpp line 156: 但是现在在palm_binary.hpp第156行的Cereal中抛出异常:

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

Here's what I'm doing: 这是我正在做的事情:

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

A Cereal Portable Binary Data Archive is constructed to hold a single vector. 构建谷物便携式二进制数据档案以保存单个矢量。 The std::ostringstream is sent off to the host using ENet. 使用ENet将std :: ostringstream发送到主机。

This part seems to work okay, I can print the information out before and after and it appears to be the same, albeit some weird symbols, but they print out the same on both ends. 这部分似乎工作正常,我可以在之前和之后打印信息,它看起来是相同的,虽然有一些奇怪的符号,但它们在两端都打印出相同的信息。

Now a std::istringstream is created on the host with the data we received. 现在,在主机上使用我们收到的数据创建了一个std :: istringstream。

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

At this point I receive the exception at line: 此时我收到了行中的异常:

Archive(PacketData)

I have a feeling the data is being changed somehow when it's sent through ENet and/or I'm not pulling the data out of the std::ostringstream correctly and/or not putting the data back into the std::istringstream correctly. 我感觉数据在通过ENet发送时以某种方式被更改和/或我没有正确地从std :: ostringstream中提取数据和/或没有正确地将数据放回到std :: istringstream中。

Thank you very much for your time I greatly appreciate it. 非常感谢您的时间,我非常感谢。

Disclaimer: I'm not familiar with enet. 免责声明:我不熟悉enet。

You are getting this error because you aren't constructing the std::stringstream properly upon receiving the packet. 您收到此错误是因为您没有在收到数据包时正确构造std::stringstream A send/receive pair should look something like: 发送/接收对应该类似于:

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
}

And then on the receiving end, something like this: 然后在接收端,这样的事情:

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

The basic idea here: use cereal and some ostringstream to generate a string (which is really just an array of bytes), send those raw bytes over the network, pull them into an istringstream, and then have cereal parse that. 这里的基本思想是:使用cereal和一些ostringstream生成一个字符串(实际上只是一个字节数组),通过网络发送这些原始字节,将它们拉入istringstream,然后对其进行解析。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM