Socket 网络字节顺序 - 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
$>