首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >二进制协议-字节交换技巧

二进制协议-字节交换技巧
EN

Stack Overflow用户
提问于 2009-03-14 22:20:15
回答 7查看 2.4K关注 0票数 4

假设我们有一个二进制协议,字段网络排序(big endian)。

代码语言:javascript
复制
struct msg1
{
    int32 a;
    int16 b;
    uint32 c
}

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

我重新排列/反转msg1以

代码语言:javascript
复制
struct msg1
{
    uint32 c
    int16 b;
    int32 a;
}

只需从网络缓冲区进行反向复制即可创建msg1。在这种情况下,不需要networkToHost函数。这种惯用的方法在大端机器上不起作用,但对我来说这不是问题。除此之外,我还遗漏了其他缺点吗?

谢谢

附注:对于以上内容,我们执行严格的对齐(#pragma pack(1)等)

EN

回答 7

Stack Overflow用户

发布于 2009-03-14 22:57:22

除此之外,我还遗漏了其他缺点吗?

恐怕您误解了字节顺序转换问题的本质。"Big endian“并不意味着您的字段是反向布局的,因此

代码语言:javascript
复制
struct msg1_bigendian
{
    int32 a;
    int16 b;
    uint32 c
}

在大端架构上相当于一个

代码语言:javascript
复制
struct msg1_littleendian 
{
   uint32 c;
   int16 b;
   int32 a;
}

一个小的endian架构上。相反,这意味着每个字段中的字节顺序是颠倒的。让我们假设:

代码语言:javascript
复制
a = 0x1000000a;
b = 0xb;
c = 0xc;

在大端架构上,这将被安排为:

代码语言:javascript
复制
10 00 00 0a
00 0b
00 00 00 0c

高位(最高有效)字节最先出现。

在小端机器上,这将被设置为:

代码语言:javascript
复制
0a 00 00 10
0b 00
0c 00 00 00

最低位字节在前,最高位字节在最后。

序列化它们,并将消息的序列化形式覆盖在彼此的顶部,您将发现不兼容性:

代码语言:javascript
复制
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

请注意,这不是简单的字段反向运行的情况。您的建议将导致一台小的endian机器将大端表示形式误认为:

A= 0xc000000;b= 0xb00;c= 0xa000010;

当然不是传输的内容!

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

更新:

好了,我知道你现在想做什么了。您希望反向定义struct,然后从字节字符串的末尾到开头定义memcpy (反向复制),并以这种方式颠倒字节顺序。在这种情况下,我会说,是的,这是一个黑客攻击,是的,它使你的代码不可移植,是的,这是不值得的。事实上,字节顺序之间的转换并不是一个非常昂贵的操作,而且它比颠倒每个结构的布局要容易得多。

票数 20
EN

Stack Overflow用户

发布于 2009-03-14 22:23:51

您确定这是必需的吗?更有可能的是,您的网络流量将成为瓶颈,而不是CPU速度。

票数 6
EN

Stack Overflow用户

发布于 2009-03-14 22:28:17

同意@ribond

这很有可能会让开发人员非常困惑,因为他们必须努力将这些结构保持在语义上相同的结构中。

考虑到网络延迟比CPU处理它要慢10,000,000倍,我只想保持它们不变。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/646842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档