如何解释 C++ 中的二进制数据?
我正在以数据包(64 字节)的形式向设备发送和接收二进制数据。 数据具有特定的格式,部分格式随着不同的请求/响应而变化。
现在我正在为接收到的数据设计一个解释器。 简单地按位置读取数据就可以了,但是当我有十几种不同的响应格式时,看起来就不那么酷了。 我目前正在考虑为此目的创建一些结构,但我不知道它如何与填充一起使用。
也许有更好的方法?
相关:
I am sending and receiving binary data to/from a device in packets (64 byte). The data has a specific format, parts of which vary with different request / response.
Now I am designing an interpreter for the received data. Simply reading the data by positions is OK, but doesn't look that cool when I have a dozen different response formats. I am currently thinking about creating a few structs for that purpose, but I don't know how will it go with padding.
Maybe there's a better way?
Related:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您需要使用结构和/或联合。 您需要确保连接两端的数据都正确打包,并且如果连接的任何一端有可能运行不同的网络字节顺序,您可能需要在每一端进行网络字节顺序的转换。字节顺序。
举个例子:
然后分配时:
然后接收时:
下面是一些关于 Endianness 的讨论和对齐和结构打包
如果您不这样做如果不打包结构,它最终会与字边界对齐,并且结构的内部布局及其大小将不正确。
You need to use structs and or unions. You'll need to make sure your data is properly packed on both sides of the connection and you may want to translate to and from network byte order on each end if there is any chance that either side of the connection could be running with a different endianess.
As an example:
and then when assigning:
and then when receiving:
Here are some discussions of Endianness and Alignment and Structure Packing
If you don't pack the structure it'll end up aligned to word boundaries and the internal layout of the structure and it's size will be incorrect.
我以前已经做过无数次了:这是一个非常常见的场景。 有很多事情我几乎总是做。
不要太担心让它成为最有效的东西。
如果我们确实花费了大量时间打包和拆包数据包,那么我们总是可以更改它以提高效率。 虽然我还没有遇到过必须这样做的情况,但我还没有实现网络路由器!
虽然使用结构/联合是运行时最有效的方法,但它带来了许多复杂性:说服编译器打包结构/联合以匹配所需数据包的八位字节结构,努力避免对齐和字节顺序问题,并且缺乏安全性,因为没有或很少有机会对调试版本进行健全性检查。
我经常会得到一个包含以下内容的体系结构:
在所有这些中,可以(即使只是为了调试版本)验证每个可修改的字段是否被设置为合理的值。 虽然看起来工作量很大,但它使得很难获得无效格式的数据包,可以使用调试器轻松地通过肉眼检查预打包的数据包内容(因为它都是正常的平台本机格式变量)。
如果我们确实必须实现更高效的存储方案,那么也可以将其包含在这个抽象中,而几乎不需要额外的性能成本。
I've done this innumerable times before: it's a very common scenario. There's a number of things which I virtually always do.
Don't worry too much about making it the most efficient thing available.
If we do wind up spending a lot of time packing and unpacking packets, then we can always change it to be more efficient. Whilst I've not encountered a case where I've had to as yet, I've not been implementing network routers!
Whilst using structs/unions is the most efficient approach in term of runtime, it comes with a number of complications: convincing your compiler to pack the structs/unions to match the octet structure of the packets you need, work to avoid alignment and endianness issues, and a lack of safety since there is no or little opportunity to do sanity checks on debug builds.
I often wind up with an architecture including the following kinds of things:
In all of this, it's possible (even if just for debug builds) to verify that each field which is modifiable is being set to a sane value. Whilst it might seem like a lot of work, it makes it very difficult to have an invalidly formatted packet, a pre-packed packets contents can be easilly checked by eye using a debugger (since it's all in normal platform-native format variables).
If we do have to implement a more efficient storage scheme, that too can be wrapped in this abstraction with little additional performance cost.
在不知道数据的确切格式的情况下,很难说出最好的解决方案是什么。 您考虑过使用工会吗?
It's hard to say what the best solution is without knowing the exact format(s) of the data. Have you considered using unions?
我同意伍吉的观点。 您还可以使用代码生成来执行此操作。 使用一个简单的数据定义文件来定义所有数据包类型,然后对其运行 python 脚本以生成原型结构和每个数据包类型的序列化/反序列化函数。
I agree with Wuggy. You can also use code generation to do this. Use a simple data-definition file to define all your packet types, then run a python script over it to generate prototype structures and serialiation/unserialization functions for each one.
这是一个“开箱即用”的解决方案,但我建议看一下 Python 构造 库。
构造非常健壮和强大,仅仅阅读教程将帮助您更好地理解问题。 作者还计划从定义自动生成 C 代码,因此绝对值得花精力去阅读。
This is an "out-of-the-box" solution, but I'd suggest to take a look at the Python construct library.
construct is very robust and powerful, and just reading the tutorial will help you understand the problem better. The author also has plans for auto-generating C code from definitions, so it's definitely worth the effort to read about.