哪种流适合通过 UDP 进行序列化?

Which stream is suitable for serialization over UDP?

我正在尝试使用 Boost.Serialization and Boost.Asio 库通过 UDP 序列化和恢复对象。以下几点总结了我目前所知道的:

来源:https://theboostcpplibraries.com/boost.serialization-archive

我知道我必须将流作为参数传递给存档。但是,有几种不同类型的流是合适的候选者。见下图:

来源:

我看到在线连载示例使用了ostreamistream,其他示例使用了ostringstreamistringstream,还有一些使用了streambuf,这如果我没记错的话,它既可以作为输入缓冲区,也可以作为输出缓冲区。

(文件流不在等式中,因为我需要从套接字而不是文件中 write/read。)

花时间阅读您在cppreference.com Input/output library中提到的流的描述,很有启发性。

如果您想序列化到内存中,只有一种流适合您:ostringstream。然后你从中提取字符串并发送它。对于反序列化,请使用 istringstream。或者,对于这两种情况,stringstream

补充一下 Maxim 的回答,如果你真的想使用 UDP,你需要注意将你的流拆分成数据报,并自己确保数据流的一致性。 UDP 是面向数据报的,不保证数据一致性。

使用UDP需要注意的事项:

  • 数据报可能会在传输过程中丢失。
  • 数据报可能到达不止一次。
  • 数据报可能在传输过程中损坏(有校验和,但它是可选的且很弱)。
  • 数据报可能会乱序到达。
  • 网络或收件人的带宽可能不足以支持发件人的发送速率。

如果其中任何一个成为问题,您需要实施适当的对策作为协议的一部分,例如数据包序列号和请求数据包重传的方法。

大型数据报可能会变得碎片化并严重降低性能。有些人建议最大数据报大小为 512 字节。

因此,考虑到这些限制,我建议使用 compact 二进制序列化格式。例如,protobuf 或 msgpack。 Boost 不是很紧凑,但足够好(来源:cpp-serializers)。