gpt4 book ai didi

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

转载 作者:太空狗 更新时间:2023-10-29 21:21:18 34 4
gpt4 key购买 nike

几周来,我一直致力于将 ENet 包装成一组易于使用的函数,但似乎遇到了一些问题。

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

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

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

但是现在在 portable_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);
}

Cereal Portable Binary Data Archive 被构建为保存单个 vector 。std::ostringstream 使用 ENet 发送到主机。

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

现在 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正确。

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

最佳答案

免责声明:我不熟悉 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 );
}
}

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

关于c++ - 使用 ENet 从 Cereal 发送二进制数据的 StringStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22799551/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com