当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《二进制协议-字节交换技巧》经验,为你挑选了3个好方法。

假设我们有一个二进制协议,字段网络有序(大端).

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)等)



1> cygil..:

除此之外,我还有其他任何缺点吗?

我担心你误解了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,并以这种方式反转字节顺序.在这种情况下,我会说,是的,这是一个黑客,是的,它使你的代码不可移植,是的,它是不值得的.事实上,在字节顺序之间进行转换并不是一项非常昂贵的操作,并且它比处理每个结构的布局要容易得多.



2> rlbond..:

你确定这是必需的吗?您的网络流量很可能是您的瓶颈,而不是CPU速度.



3> codekaizen..:

同意@ribond -

这对于开发人员来说非常容易混淆,因为他们必须努力将这些与语义相同的结构分开.

鉴于网络延迟比CPU处理它的速度快10,000,000倍,我只是保持它们相同.

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有