将大端结构转换成小端

我正在制作一个C程序,与使用大端字节排序的患者监视器进行通信。 例如,如果我有一定的C结构

typedef struct {
   int short a;
   int short b;
   int       c;
} msg;

要阅读这种结构,我可以简单地使用ntohs(msg.a),ntohs(msg.b),ntohl(msg.c)。 但是一些结构有一个短整数的缓冲区,但缓冲区本身就是另一个结构的类型。 例如,

typedef struct {
   int short length;
   int short b[MAX_BUF_SIZE];
} msg1;

上述结构中的字段“b”代表另一种结构,其结构如下:

typedef struct {
   int short a;
   int short b;
} msg2;

现在,我的问题是1)我应该将所有结构“msg1”的短整数转换为主机顺序,然后将其转换为类型“msg2”的指针,并简单地读取“msg2.a”和“msg2.b”或2)我应该转换“msg2.a”和“msg2.b”的字节顺序,或者3)只将“msg1.b”转换为类型“msg2”的指针并读取“msg2.a”和“msg2.b”通过将它们中的每一个转换为主机命令?

请告诉哪一种方法是正确的读取msg1

方法1

int t[msg1.length];
for(int i = 0; i < msg1.length; i++)
   t[i] = ntohs(*(msg1.b + i));
msg2 * msg2_m = (msg2 *)t;
/* should I convert the msg2_m.a and msg2_m.b as well? */
printf("%d:%d", msg2_m.a, msg2_m.b);

方法2

除了所有相同

printf("%d:%d", ntohs(msg2_m.a), ntohs(msg2_m.b));

方法3

不转换“msg1.b”并直接将“msg1.b”转换为“msg2”,只是将“msg2.a”和“msg2.b”转换为主机命令。

msg2 *msg2_m = (msg2 *)msg1.a;
printf("%d:%d", ntohs(msg2_m.a), ntohs(msg2_m.b));

我需要了解何时将结构转换为其他结构时,它的字节顺序是否在通过网络传递时根据新结构进行更改? 我认为方法3是正确的,但那只是我,我不确定字节顺序的内部。 任何帮助,将不胜感激。

谢谢,Shivam Kalra


首先,转换不会影响字节顺序。

其次,你不想在你的代码中的任何地方考虑字节顺序,因为你或别人会忘记并在某个地方犯了错误,而且以后会试图找到这个错误。 所以,只要您读取数据,将其转换为正确的字节顺序。 如果您读取包含短裤数组的结构,请立即将整个短裤数组转换为正确的字节顺序。 其他结构也是如此。 转换数据并存储结果; 每次您需要阅读或打印某些内容时,请勿使用ntohs。 从程序的其余部分分离此代码,以便在程序的其他部分忘记字节顺序,并在处理转换代码时仅考虑字节顺序。


我认为最好不要试图直接读或写struct 。 相反,你应该明确地定义你的连线格式并将你的结构逐字节地写入(然后在读取时做相反的操作)。 例如,要写:

typedef struct {
   short int a;
   short int b;
   int       c;
} msg;

你可以做:

void WriteBigEndian16(uint16_t x, FILE* fp)
{
   fputc((x >> 8) & 0xFF, fp);
   fputc( x       & 0xFF, fp);
}

void WriteBigEndian32(uint32_t x, FILE* fp)
{
   fputc((x >> 24) & 0xFF, fp);
   fputc((x >> 16) & 0xFF, fp);
   fputc((x >>  8) & 0xFF, fp);
   fputc( x        & 0xFF, fp);
}

FILE* fp = fopen(...);
msg m; // Assume that this is initialized.
WriteBigEndian16(m.a, fp);
WriteBigEndian16(m.b, fp);
WriteBigEndian32(m.c, fp);

这具有以下优点:

  • 该代码是endian不可知的。 无论你是在一台小型机器还是一台大型机器上运行,都无关紧要。 你不需要知道。
  • 你避免了关于你的内存struct是否是字节交换的混淆。 无论平台的本地订购是什么,它们都将始终如一。
  • 你也正在定义你的领域的大小。 如果你没有定义你的连线格式,你不仅容易出现endian不匹配,而且容易出现大小不匹配。 谁说这两个端点对int都使用相同的大小?
  • 链接地址: http://www.djcxy.com/p/61899.html

    上一篇: Converting big endian structures to little endian

    下一篇: reading in C++ a socket open by Java + structure alignment