gpt4 book ai didi

c++ - 二进制协议(protocol) - 字节交换技巧

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:53:00 25 4
gpt4 key购买 nike

假设我们有一个二进制协议(protocol),其中的字段按网络顺序排列(大端)。

struct msg1
{
int32 a;
int16 b;
uint32 c
}

如果不是将网络缓冲区复制到我的 msg1,然后使用“networkToHost”函数读取 msg1

我将 msg1 重新排列/反转为

struct msg1
{
uint32 c
int16 b;
int32 a;
}

然后简单地从网络缓冲区做一个反向复制来创建 msg1。在这种情况下,不需要 networkToHost 函数。这种惯用的方法在大端机器上不起作用,但对我来说这不是问题。除此之外,还有其他我想念的缺点吗?

谢谢

附言对于以上内容,我们强制执行严格对齐(#pragma pack(1) 等)

最佳答案

除此之外,还有其他我想念的缺点吗?

恐怕您误解了端序转换问题的本质。 “Big endian”并不意味着您的字段是反向排列的,因此

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;

当然不是传输的内容!

对于传输的每个字段,您确实必须将每个单独的字段转换为网络字节顺序,然后再转换回来。

更新:

好的,我明白你现在想做什么了。您想要反向定义结构,然后从字节字符串的 end 到开头进行 memcpy(反向复制)并以这种方式反转字节顺序。在这种情况下,我会说,是的,这是一个 hack,是的,它使您的代码不可移植,是的,这是不值得的。事实上,字节顺序之间的转换并不是一个非常昂贵的操作,而且它比反转每个结构的布局更容易处理。

关于c++ - 二进制协议(protocol) - 字节交换技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/646842/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com