gue*_*est 5 c c++ encoding serialization struct
我需要以相当高的更新速率通过线路发送C结构(使用UDP套接字,并且可能在某些时候使用XDR),这可能会导致大量冗余和不必要的流量达到几khz.
这是因为,结构中的某些数据有时可能没有变化,所以我认为对当前的C结构进行delta编码与先前的C结构相比似乎是一个好主意,非常像"差异".
但我想知道,做这样的事情的最佳方法是什么,理想情况是以可移植的方式确保数据完整性得以维持?是否可以简单地对数据进行异或,并按此进行?
类似地,重要的是该方法保持足够的可扩展性,以便可以将新字段添加到结构中或在必要时重新排序(填充),这听起来好像它还需要版本信息.
任何想法或指针(是否有现有的图书馆?)将受到高度赞赏!
谢谢
编辑:感谢所有提供答案的人,真的很感激细节,我意识到我可能不应该提到UDP,因为这实际上不是主要问题,因为已经有相应的协议实现了解决上述困难的UDP的顶部,所以问题实际上是特定于delta编码结构的可行方法,而不是特别使用UDP作为传输机制.
UDP 不保证实际收到给定的数据包,因此将您传输的任何内容编码为“与上次的差异”是有问题的 - 您无法知道您的对方对“上次”的想法与您相同曾是。本质上,您必须在 UDP 之上建立一些开销来检查已收到哪些数据包(用唯一的 ID 标记每个数据包)——每个尝试走这条路线的人都会同意,您通常会发现自己更多或更少地重复 UDP 之上的 TCP 流基础设施……只是,很可能,没有那么可靠和完善(尽管不可否认,有时您可以利用有效负载的非常特殊的特征,以获得一些相对于普通良好的适度优势)旧的 TCP)。
您的传输是否需要是单向的,从发送者到接收者?如果是这种情况(即,接收方发送确认或重传是不可接受的),那么您实际上无能为力。我想到的一件事是:如果接收方暂时不同步是可以接受的,那么发送方可以发送两种数据包——一种包含结构体当前值的完整图片,另一种包含一个标识。独特的标签,至少每(比如)5 分钟发送一次(因此实际上,如果接收器错过了其中两个“大数据包”,则接收器可能会不同步长达 15 分钟);一个仅包含最后一个“大数据包”的更新(差异),包括大数据包的识别唯一标签和(例如)您提到的 XOR 的运行长度编码版本。
当然,一旦准备好游程编码版本,服务器将比较其大小与整个结构的大小,并且仅在节省很大的情况下才发送增量类型的数据包,否则它可能会发送大的数据包。 - 比需要的时间早一点发送数据包(提高可靠性)。接收到的数据包将跟踪它收到的最后一个大数据包唯一标签,并且仅应用与其相关的增量(有助于防止丢失数据包和乱序交付的数据包,具体取决于您想让客户端变得多么复杂)。
版本控制 &c 的需要,取决于您的确切含义(对于结构的 C 布局应该如何看起来有不同想法的发送者和接收者是否需要定期沟通?他们如何握手双方都知道哪些版本?等等),将添加更复杂的宇宙,但这实际上是另一个问题,标题中总结的核心问题已经足够大了;-)。
如果您可以承受偶尔从接收方返回发送方的元消息(确认或请求重新发送),那么根据所使用的各种数字参数,您可以设计不同的策略。我怀疑确认必须非常频繁才能发挥作用,因此重新发送大数据包的请求(无论是专门识别的数据包还是“无论您拥有什么最新的数据包”)可能是剔除选项空间的最佳元策略(否则有爆炸的危险;-)。如果是这样,那么发送方可能完全不知道接收方用于请求大数据包重新发送的任何策略,并且您可以在接收方使用各种此类策略进行实验,而无需重新部署发送方。
如果没有一些具体细节,就很难提供更多帮助,即至少所有数字参数的大概数字——数据包大小、发送频率、发送方与接收方不同步的容忍时间、捆绑包但我希望这些通用的分析和建议仍然有帮助。