zoo*_*opa 4 c c++ sockets network-programming payload
如果您将以下类作为网络数据包负载:
class Payload {char field0; int field1; char field2; int field3; };
在通过套接字接收数据时,使用像Payload这样的类是否会使数据的接收者容易出现对齐问题?我认为该类要么需要重新排序,要么添加填充以确保对齐.
要么重新排序:
class Payload
{
int field1;
int field3;
char field0;
char field2;
};
Run Code Online (Sandbox Code Playgroud)
或添加填充:
class Payload
{
char field0;
char pad[3];
int field1;
char field2;
char pad[3];
int field3;
};
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因重新排序没有意义,我认为添加填充将是首选,因为它会避免对齐问题,即使它会增加类的大小.
您对网络数据中的这种对齐问题有什么经验?
正确,盲目地忽略对齐可能会导致问题.即使在相同的操作系统上,如果使用不同的编译器或不同的编译器版本编译了2个组件.
最好......
1)通过某种序列化过程传递数据.
2)或者单独传递每个原语,同时仍然注意字节排序== Endianness
一个好的起点是Boost Serialization.
您应该研究Google protocol buffers,或像另一位海报所说的 Boost::serialize 。
如果您想自己推出,请正确操作。
如果您使用 stdint.h 中的类型(即:uint32_t, int8_t,
等),并确保每个变量都具有“本机对齐”(意味着其地址可被其大小整除(int8_t
s 可以在任何地方,uint16_t
s 位于偶数地址上,uint32_t
s 位于地址上)可被 4 整除),您不必担心对齐或打包问题。
在之前的工作中,我们通过 XML 定义的数据总线(以太网、CANbus、byteflight 或串行端口)发送所有结构。有一个解析器可以验证结构内变量的对齐情况(如果有人编写了错误的 XML,则会发出警报),然后为各种平台和语言生成头文件以发送和接收结构。这对我们来说非常有效,我们永远不必担心手写代码来进行消息解析或打包,并且保证所有平台都不会出现愚蠢的小编码错误。我们的一些数据链路层的带宽非常有限,因此我们实现了位字段之类的东西,并让解析器为每个平台生成正确的代码。我们还有枚举,这非常好(你会惊讶地发现,对于人类来说,手动搞砸枚举上的位域编码是多么容易)。
除非你需要担心它在带有 C 的 8051 和 HC11 上运行,或者在带宽非常受限的数据链路层上运行,否则你不会想出比协议缓冲区更好的东西,你只会花很多时间尝试与他们平起平坐。