用htons确定字节序

时间:2016-12-30 03:24:42

标签: c linux network-programming endianness

请考虑以下代码:

#include <stdio.h>
#include <arpa/inet.h>

int main(int argc, char *argv[]) {
    uint16_t num = 123;

    if (htons(num) == num) {
        printf("big endian\n");
    } else {
        printf("little endian\n");
    }
}

我想知道这段代码是否适用于检查字节序?我已经看到很多问题用各种指针/字符技巧检查它,但我认为这更简单。它的假设是,如果将数字转换为网络字节顺序(大端),如果它与原始数字相同,那么你就是一个大端系统。否则你就是一个小端系统。

这张支票是否有错误的假设?也许网络字节顺序并不总是大端,但it seems it is standardised to be so

2 个答案:

答案 0 :(得分:6)

这足以在运行时检查字节顺序。

在大端系统上,htons(以及ntohshtonlntohl)被定义为无操作,而在小端系统上,它们执行一个字节交换。

编辑:

这也可以使用union来完成。下面的检查检测大端和小端,以及其他更奇特的字节排序。

#include <stdio.h>
#include <stdint.h>

union echeck {
    uint32_t i;
    char c[4];
} echeck = { .c = { 0x01, 0x02, 0x03, 0x04 } };

int main()
{
    if (echeck.i == 0x01020304) {
        printf("big endian\n");
    } else if (echeck.i == 0x04030201) {
        printf("little endian\n");
    } else if (echeck.i == 0x02010403) {
        printf("pdp endian\n");
    } else {
        printf("other endian\n");
    }
    return 0;
}

答案 1 :(得分:2)

原则上,C允许uint16_t表示中的位处于任何实现定义的顺序,而不仅仅是“小”或“大端”。如上所述,您的测试仅告诉您htons分别置换位0,1,3,4,5,6和2,7-15而不混合它们。

如果你迭代所有2的幂并在0..15中找到htons(1<<i)==1<<i的{​​{1}},那么你可以得出结论,该命令肯定是大端。如果您在0..15中找到i的{​​{1}},则可以得出小端。否则你会有一个非常不寻常的代表。

实际上,奇怪的事情不会发生,你的测试应该足够了。