主机序和网络序及其转换函数


  在物联网或者网络通信的过程中难免会发生数据的交换,因为每台主机不同,其存储数据方式可能为 大端存储(Big endian)小端存储(Little endian),因此在数据传输的过程中是 以网络字节序为标准顺序,考虑与协议的一致性,在程序发送数据包的过程中,将主机字节序转为网络字节序,收到数据包的主机再将网络字节序转为该主机的主机字节序,从而完成两台主机的通信。因此掌握主机存储数据的方式其转换机制是很有必要的。

主机字节序

  在不同的CPU处理器下,有不同的字节序类型,而字节序是指整数在内存中存储的顺序叫做主机序。最常见的主机序有两种:

  • 大端存储(Big endian):最高有效位存于最低内存地址处,最低有效位存于最高内存处。(最直观的字节序,即数据位从左到右的顺序按照从低到高顺序写出即为内存地址。
  • 小端存储(Little endian):最高有效位存于最高内存地址处,最低有效位存于最低内存处。(符合人思维的字节序低地址存低位)
    通过下面的图可以更加方便地理解和记忆大小端主机序的概念。
               在这里插入图片描述
      在《UNIX网络编程卷一》这本书中有介绍到如何确定自己的主机是大端序还是小端序(务必要记住如何判断,笔试面试可能会考到):
#include <stdio.h>
#include <stdlib.h>

int main()
{
    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) = %ld\n", sizeof(short));
    exit(0);
}

  编译执行后就会显示:

panghu@Ubuntu-14:~/apue/socket/socket/apue_studay/lixinlei$ ./test 
Little-Endian

网络字节序

  网络字节序是TCP/IP中规定好的一种数据表示格式,他与CPU类型,操作系统无关,是可以保证数据在不同主机之间传输能够被正确解释的一种标准,网络字节序是采用大端存储(Big endian)
  为了实现两个存储方式不同的主机在传输时,需要借助字节序转换函数。

#include<arpa/inet.h>
// h-主机 n-网络 s-short l-long
//主机字节序转为网络字节序
unit32_t htonl (unit32_t hostlong);  
unit16_t htons (unit16_t hostshort);
//网络字节序转为主机字节序
unit32_t ntohl (unit32_t netlong);
unit16_t ntohs (unit16_t netshort);

  示例代码如下

#include <stdio.h>
#include <stdlib.h>
int main(){
unsigned short host_port = 0x1234, net_port;
unsigned long host_addr = 0x12345678, net_addr;

net_port = htons(host_port);
net_addr = htonl(host_addr);

printf("Host ordered port: %#x\n", host_port);
printf("Network ordered port: %#x\n", net_port);
printf("Host ordered address: %#lx\n", host_addr);
printf("Network ordered address: %#lx\n", net_addr);
return 0;
}

  运行结果:

Host ordered port: 0x1234
Network ordered port: 0x3412
Host ordered address: 0x12345678
Network ordered address: 0x78563412
发布了11 篇原创文章 · 获赞 3 · 访问量 295

猜你喜欢

转载自blog.csdn.net/weixin_42647166/article/details/104673368