使用“char”进行网络字节顺序转换

时间:2010-03-01 17:32:45

标签: c++ network-programming

我一直被告知,如果整数大于char,则必须解决字节排序问题。通常,我只是将它包装在hton [l | s]中并用ntoh [l | s]将其转换回来。但我很困惑,为什么这不适用于单字节字符。

我很想知道为什么会这样,并且希望经验丰富的网络程序员帮助我解释为什么字节排序仅适用于多字节整数。

参考:https://beej.us/guide/bgnet/html/multi/htonsman.html

7 个答案:

答案 0 :(得分:21)

您要找的是endianness

big-endian架构存储多字节数据类型的字节,如下所示:

big-endian

而little-endian架构反过来存储它们:

little-endian

当数据从一台机器传输到另一台机器时,必须重新排序单个数据类型的字节以与目标机器的字节顺序相对应。

但是当数据类型只包含一个字节时,没有任何内容需要重新排序

答案 1 :(得分:4)

您的网络堆栈将正确处理字节内的位,您只需要关注自己以正确的顺序获取字节。

答案 2 :(得分:4)

究竟有多少种方法可以在单个字符中订购字节?

答案 3 :(得分:3)

您需要考虑每个功能的作用。从那时起,您需要将该知识应用于您要修改的类型的大小。请考虑以下事项:

#include <stdio.h>
#include <netinet/in.h>

int main () {
    uint16_t i = 42;
    uint8_t c = 42; // a char
    printf ("(uint16_t ) %08X (%d)\n", i, i);
    printf ("(   htons ) %08X (%d)\n", htons(i), htons(i));
    printf ("( uint8_t ) %08X (%c)\n", c, c);
    printf ("(   htons ) %08X (%c)\n", htons(c), htons(c));
    return 0;
}

(uint16_t ) 0000002A (42)
(   htons ) 00002A00 (10752)
( uint8_t ) 0000002A (*)
(   htons ) 00002A00 ()

答案 4 :(得分:2)

您不会从线路上读取单个位,只是字节。无论字节顺序如何,单个字节都是相同的向后和向前,就像单词“I”向后和向前一样。

答案 5 :(得分:0)

除了人们所说的所有其他方式之外:Endianness大约是整数中的字节顺序,而不是字节中的位顺序。即使在big-endian和little-endian机器上,字节中的位顺序也是相同的。唯一的区别是字节本身用于存储整数(或短或有什么)的顺序。因此,因为char中只有一个字节,所以在big-endian或little-endian架构中存储该值的方式没有区别。

答案 6 :(得分:0)

ezpz代码不正确..

uint16_t i = 65534;
printf ("(uint16_t ) %08X (%d)\n", i, i);

Returns...
(uint16_t ) 0000FFFE (-2)

您应该使用unsigned int,因此它不会被解释为signed int

uint16_t i = 65534;
printf ("(uint16_t ) %08X (%u)\n", i, i);

Returns...
(uint16_t ) 0000FFFE (65534)