假设我们有一个二进制协议,字段网络有序(大端).
struct msg1 { int32 a; int16 b; uint32 c }
而不是将网络缓冲区复制到我的msg1,然后使用"networkToHost"函数来读取msg1
我将msg1重新排列/反向
struct msg1 { uint32 c int16 b; int32 a; }
并简单地从网络缓冲区执行反向复制以创建msg1.在这种情况下,不需要networkToHost功能.这种习惯用法在大端机器上不起作用,但对我来说这不是问题.除此之外,我还有其他任何缺点吗?
谢谢
PS为上面我们强制严格对齐(#pragma pack(1)
等)
除此之外,我还有其他任何缺点吗?
我担心你误解了endian转换问题的本质."大端"并不意味着你的领域是反向排列的,所以a
struct msg1_bigendian { int32 a; int16 b; uint32 c }
在大端架构上相当于一个
struct msg1_littleendian { uint32 c; int16 b; int32 a; }
在一个小端架构上.相反,它意味着每个字段内的字节顺序是相反的.我们假设:
a = 0x1000000a; b = 0xb; c = 0xc;
在大端架构上,这将被布置为:
10 00 00 0a 00 0b 00 00 00 0c
首先是高阶(最重要)字节.
在小端机器上,这将被布置为:
0a 00 00 10 0b 00 0c 00 00 00
首先是最低位字节,最后一个是最高位.
序列化它们并将消息的序列化形式叠加在一起,您将发现不兼容性:
10 00 00 0a 00 0b 00 00 00 0c (big endian) 0a 00 00 10 0b 00 0c 00 00 00 (little endian) int32 a int16 b int32 c
请注意,这不仅仅是字段反向运行的情况.您的建议会导致一个小端程序机器错误地将大端表示形式误认为:
a = 0xc000000; b = 0xb00; c = 0xa000010;
当然不是传播的东西!
对于传输的每个字段,您确实必须将每个字段转换为网络字节顺序并再次返回.
更新:
好的,我明白你现在要做什么.您希望反向定义结构,然后从字节字符串的末尾到开头(反向复制)的memcpy,并以这种方式反转字节顺序.在这种情况下,我会说,是的,这是一个黑客,是的,它使你的代码不可移植,是的,它是不值得的.事实上,在字节顺序之间进行转换并不是一项非常昂贵的操作,并且它比处理每个结构的布局要容易得多.
你确定这是必需的吗?您的网络流量很可能是您的瓶颈,而不是CPU速度.
同意@ribond -
这对于开发人员来说非常容易混淆,因为他们必须努力将这些与语义相同的结构分开.
鉴于网络延迟比CPU处理它的速度快10,000,000倍,我只是保持它们相同.