哪种流适合通过 UDP 进行序列化?
Which stream is suitable for serialization over UDP?
我正在尝试使用 Boost.Serialization and Boost.Asio 库通过 UDP 序列化和恢复对象。以下几点总结了我目前所知道的:
- Boost.Serialization 的主要概念是 存档。存档是表示序列化 C++ 对象的字节序列。
- class
boost::archive::text_oarchive
序列化数据为文本流,class boost::archive::text_iarchive
从这样的文本流恢复数据。
- 档案的构造函数需要一个输入或输出流作为参数。流用于序列化或恢复数据。
来源:https://theboostcpplibraries.com/boost.serialization-archive
我知道我必须将流作为参数传递给存档。但是,有几种不同类型的流是合适的候选者。见下图:
来源:
我看到在线连载示例使用了ostream
和istream
,其他示例使用了ostringstream
和istringstream
,还有一些使用了streambuf
,这如果我没记错的话,它既可以作为输入缓冲区,也可以作为输出缓冲区。
(文件流不在等式中,因为我需要从套接字而不是文件中 write/read。)
- advantages/disadvantages 为上述每个流提供什么?
- 考虑到我必须通过 UDP 发送序列化对象,这
stream 是最佳人选?
花时间阅读您在cppreference.com Input/output library中提到的流的描述,很有启发性。
如果您想序列化到内存中,只有一种流适合您:ostringstream
。然后你从中提取字符串并发送它。对于反序列化,请使用 istringstream
。或者,对于这两种情况,stringstream
。
补充一下 Maxim 的回答,如果你真的想使用 UDP,你需要注意将你的流拆分成数据报,并自己确保数据流的一致性。 UDP 是面向数据报的,不保证数据一致性。
使用UDP需要注意的事项:
- 数据报可能会在传输过程中丢失。
- 数据报可能到达不止一次。
- 数据报可能在传输过程中损坏(有校验和,但它是可选的且很弱)。
- 数据报可能会乱序到达。
- 网络或收件人的带宽可能不足以支持发件人的发送速率。
如果其中任何一个成为问题,您需要实施适当的对策作为协议的一部分,例如数据包序列号和请求数据包重传的方法。
大型数据报可能会变得碎片化并严重降低性能。有些人建议最大数据报大小为 512 字节。
因此,考虑到这些限制,我建议使用 compact 二进制序列化格式。例如,protobuf 或 msgpack。 Boost 不是很紧凑,但足够好(来源:cpp-serializers)。
我正在尝试使用 Boost.Serialization and Boost.Asio 库通过 UDP 序列化和恢复对象。以下几点总结了我目前所知道的:
- Boost.Serialization 的主要概念是 存档。存档是表示序列化 C++ 对象的字节序列。
- class
boost::archive::text_oarchive
序列化数据为文本流,classboost::archive::text_iarchive
从这样的文本流恢复数据。 - 档案的构造函数需要一个输入或输出流作为参数。流用于序列化或恢复数据。
来源:https://theboostcpplibraries.com/boost.serialization-archive
我知道我必须将流作为参数传递给存档。但是,有几种不同类型的流是合适的候选者。见下图:
来源:
我看到在线连载示例使用了ostream
和istream
,其他示例使用了ostringstream
和istringstream
,还有一些使用了streambuf
,这如果我没记错的话,它既可以作为输入缓冲区,也可以作为输出缓冲区。
(文件流不在等式中,因为我需要从套接字而不是文件中 write/read。)
- advantages/disadvantages 为上述每个流提供什么?
- 考虑到我必须通过 UDP 发送序列化对象,这 stream 是最佳人选?
花时间阅读您在cppreference.com Input/output library中提到的流的描述,很有启发性。
如果您想序列化到内存中,只有一种流适合您:ostringstream
。然后你从中提取字符串并发送它。对于反序列化,请使用 istringstream
。或者,对于这两种情况,stringstream
。
补充一下 Maxim 的回答,如果你真的想使用 UDP,你需要注意将你的流拆分成数据报,并自己确保数据流的一致性。 UDP 是面向数据报的,不保证数据一致性。
使用UDP需要注意的事项:
- 数据报可能会在传输过程中丢失。
- 数据报可能到达不止一次。
- 数据报可能在传输过程中损坏(有校验和,但它是可选的且很弱)。
- 数据报可能会乱序到达。
- 网络或收件人的带宽可能不足以支持发件人的发送速率。
如果其中任何一个成为问题,您需要实施适当的对策作为协议的一部分,例如数据包序列号和请求数据包重传的方法。
大型数据报可能会变得碎片化并严重降低性能。有些人建议最大数据报大小为 512 字节。
因此,考虑到这些限制,我建议使用 compact 二进制序列化格式。例如,protobuf 或 msgpack。 Boost 不是很紧凑,但足够好(来源:cpp-serializers)。