gpt4 book ai didi

c++ - 通过网络发送结构

转载 作者:行者123 更新时间:2023-11-30 02:35:31 24 4
gpt4 key购买 nike

在我们公司,通过网络发送 C/C++ 结构是很常见的。任何结构都有一个或多个 uint32_t 字段:

typedef struct {
uint32_t data1;
uint32_t data2;
} Data;

和fields(data1, data2, ...)封装了我们需要发送的真实数据。我们的数据大多只有一位或几位长,因此为了节省空间/带宽,它在特定位位置的这些字段内对齐。

为了访问我们的真实数据,我们编写了(在结构之外!)带有位移和位掩码的“getters”和“setters”宏:

#define READY_MASK 0x01      // indicates that READY is a single bit value
#define READY_OFFSET 3 // indicates position of READY inside 32-bit field
#define IS_READY(x) { ... } // returns READY value from x field
#define SET_READY(x,r) { ... } // sets READY value to x field

现在我想通过直接在结构中添加 getter 和 setter 来修改、简化并使这个过程更安全,例如:

typedef struct {
uint32_t data1;

#define READY_MASK 0x01
#define READY_OFFSET 3
inline void set_ready(uint32_t r) { /*...*/ }
inline uint32_t is_ready() { /*...*/ }
// lots of other getters and setters
} Data1;

就我的实验是正确的而言,我注意到这种修改不会影响结构的大小 sizeof(Data)==sizeof(Data1),我可以发送这种结构通过网络在另一端接收和解码。

我的问题是:这个修改有什么不对的地方吗?有什么风险或我应该注意的事情吗?

最佳答案

您所做的修改不会造成任何伤害,但也不会带来任何好处,因为结构成员无论如何都是公开的。 Data和Data1之所以大小相同,是因为你添加的是内联函数,不占用对象空间,而是用实际函数代码替换任何函数调用。

现在,如果您要通过网络发送结构和二进制数据,则必须考虑以下两个规则:

  • 按照惯例,整数值是使用网络字节顺序发送的,它是 Big Endian 而不是 x86 的 Little Endian。如果您确定所有发送和接收数据的机器都是 x86,这不是问题。但是,如果任何机器具有不同的字节序,如大字节序或无字节序(或中字节序),你就会遇到问题。例如,您可以有一个 ARM 处理器、一个 SPARC 等。在 C 中,您有以下宏:

    ntohs, htons, ntohl, htonl

  • 您还必须考虑不同的内存对齐方式。结构的内存对齐取决于体系结构、编译器和编译模式。编译器可能会添加填充(他们不能重新排序 C 中的成员,但请阅读:Can a C++ compiler re-order elements in a struct)。此外,long 等类型在 32 位和 64 位体系结构中具有不同的大小。即使可以肯定只有两个 unsigned int 成员不会有问题,您也不应该将内存从结构复制到将在消息中发送的数据缓冲区,也不应该从消息中的原始数据复制内存到一个结构。基本上你不应该做这样的事情:

    字符缓冲区[BUF_SIZE];

    Data1 myData;

    memcpy(buffer, myData, sizeof(Data));

https://en.wikipedia.org/wiki/Data_structure_alignment

你应该将成员一个一个地移动到缓冲区。当您从消息中收到的原始数据填充结构时也是如此。

我还建议不要使用位域,阅读 Why bit endianness is an issue in bitfields? .但非常清楚,在您的代码片段中您没有使用位域。使用位域与使用整数中的位来表示某些特定状态不同。在这种情况下,你做得很好,应该只考虑具有不同字节顺序的架构中的整数表示(如果这是可能的情况)。

关于c++ - 通过网络发送结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33521535/

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