Unix Sockets 简明教程
Unix Socket - Network Byte Orders
不幸的是,并非所有计算机都以相同的顺序存储构成多字节值的那个字节。考虑一个由 2 个字节组成的 16 位互联网。有两种方法来存储此值。
-
Little Endian − 在此方案中,低位字节存储在起始地址 (A) 上,而高位字节存储在下一个地址 (A + 1) 上。
-
Big Endian − 在此方案中,高位字节存储在起始地址 (A) 上,而低位字节存储在下一个地址 (A + 1) 上。
为了允许具有不同字节顺序约定的机器互相通信,因特网协议为通过网络传输的数据指定了一个规范的字节顺序约定。这被称为网络字节顺序。
在建立 Internet 套接字连接时,您必须确保 sockaddr_in 结构的 sin_port 和 sin_addr 成员中的数据以网络字节顺序表示。
Byte Ordering Functions
用于在主机内部表示和网络字节顺序之间转换数据的例程如下 -
Function |
Description |
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 位量从网络字节顺序转换为主机字节顺序。
这些函数是宏,并导致将转换源代码插入到调用程序中。在小端机器上,代码会将值更改为网络字节顺序。在大型机器上,不插入任何代码,因为不需要这些代码;这些函数被定义为 null。
Program to Determine Host Byte Order
将以下代码保存在一个名为 byteorder.c 的文件中,然后编译它并在机器上运行。
在此示例中,我们将两个字节值 0x0102 存储在 short integer 中,然后查看两个连续的字节 c[0](地址 A)和 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
$>