假设我们有一个二进制协议,字段网络排序(big endian)。
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)等)
发布于 2009-03-14 22:57:22
除此之外,我还遗漏了其他缺点吗?
恐怕您误解了字节顺序转换问题的本质。"Big endian“并不意味着您的字段是反向布局的,因此
struct msg1_bigendian
{
int32 a;
int16 b;
uint32 c
}在大端架构上相当于一个
struct msg1_littleendian
{
uint32 c;
int16 b;
int32 a;
}一个小的endian架构上。相反,这意味着每个字段中的字节顺序是颠倒的。让我们假设:
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请注意,这不是简单的字段反向运行的情况。您的建议将导致一台小的endian机器将大端表示形式误认为:
A= 0xc000000;b= 0xb00;c= 0xa000010;
当然不是传输的内容!
对于传输的每个字段,您确实必须将每个单独的字段转换为网络字节顺序,然后再转换回来。
更新:
好了,我知道你现在想做什么了。您希望反向定义struct,然后从字节字符串的末尾到开头定义memcpy (反向复制),并以这种方式颠倒字节顺序。在这种情况下,我会说,是的,这是一个黑客攻击,是的,它使你的代码不可移植,是的,这是不值得的。事实上,字节顺序之间的转换并不是一个非常昂贵的操作,而且它比颠倒每个结构的布局要容易得多。
发布于 2009-03-14 22:23:51
您确定这是必需的吗?更有可能的是,您的网络流量将成为瓶颈,而不是CPU速度。
发布于 2009-03-14 22:28:17
同意@ribond
这很有可能会让开发人员非常困惑,因为他们必须努力将这些结构保持在语义上相同的结构中。
考虑到网络延迟比CPU处理它要慢10,000,000倍,我只想保持它们不变。
https://stackoverflow.com/questions/646842
复制相似问题