Socket 网络字节顺序
不幸的是,所有的计算机的字节存储在相同的顺序组成的多字节值。请考虑,是由2个字节的一个16位的基于整数。有两种方法来存储这个值。
-
Little Endian: 在这个方案中,低位字节存储在起始地址(A)和高位字节存储的下一个地址(A + 1).
-
Big Endian: 在这个方案中的高位字节的开始地址(A),并存储在低位字节的下一个地址上存储(A+1).
因此,不同字节顺序的惯例,机器可以进行通信,互联网协议指定一个规范的字节顺序公约“在网络上传输的数据。这被称为网络字节顺序。
建立因特网套接字连接时,必须确保域sin_port和sin_addr成员sockaddr_in结构中的数据在网络字节顺序表示。
字节排序功能:
主机的内部表示,网络字节顺序之间转换数据的例程:
函数 | 描述 |
---|---|
htons() | Host to Network Short |
htonl() | Host to Network Long |
ntohl() | Network to Host Long |
ntohs() | Network to Host Short |
下面是这些功能的更详细:
-
unsigned short htons(unsigned short hostshort)
此功能从主机字节顺序到网络字节顺序的16位(2字节)为单位批量转换。 -
unsigned long htonl(unsigned long hostlong)
此功能将32位(4字节)的数量从主机字节顺序到网络字节顺序。 -
unsigned short ntohs(unsigned short netshort)
此功能从网络字节顺序,16位(2字节)为单位批量转换为主机字节顺序。 -
unsigned long ntohl(unsigned long netlong)
此功能将32位数量从网络字节顺序转换为主机字节顺序。
这些功能是在转换的源代码插入到调用程序中的宏和结果。在little-endian的机器代码将改变周围的值转换为网络字节顺序。在大端机器没有插入代码,因为没有需要的功能定义为空(null).
程序来确定主机字节顺序:
请将下面的代码在一个文件byteorder.c和,然后在机器上编译并运行它。
在这个例子中,我们两个字节值0x0102储存在短整型,然后看看在连续两个字节,c[0](地址)和c[1](地址A+1),以确定字节顺序。
#include <stdio.h> int main(int argc, char **argv) { union { short s; char c[sizeof(short)]; }un; un.s = 0x0102; if (sizeof(short) == 2) { if (un.c[0] == 1 && un.c[1] == 2) printf("big-endian\n"); else if (un.c[0] == 2 && un.c[1] == 1) printf("little-endian\n"); else printf("unknown\n"); } else{ printf("sizeof(short) = %d\n", sizeof(short)); } exit(0); } |
这个程序产生在奔腾机器上的输出如下:
$> gcc byteorder.c $> ./a.out little-endian $> |