大端小端与网络字节序

在裘宗燕翻译的《程序设计实践》里,这对术语并没有翻译为“大端”和小端,而是“高尾端”“低尾端”,这就好理解了:如果把一个数看成一个字符串,比如11223344看成"11223344",末尾是个'\0','11'到'44'个占用一个存储单元,那么它的尾端很显然是44,前面的高还是低就表示尾端放在高地址还是低地址,它在内存中的放法非常直观,如下图:

#include <iostream>

using namespace std;
int main()
{
    int nNum = 0x12345678;
    char chData = *(char*)(&nNum);

    if (chData == 0x12)
    {
        cout << "big" << endl;
    }
    else
    {
        cout << "small" << endl;
    }

    system("PAUSE");

    return 0;
}

网络字节序

字节序

         大端字节序(BigEndian)

最高有效位(MSB:MostSignificant Bit)存储于最低内存地址处,最低有效位(LSB:Lowest Significant Bit)存储于最高内存地址处。

        小端字节序(LittleEndian)

最高有效位(MSB:MostSignificant Bit)存储于最高内存地址    处,最低有效位(LSB:LowestSignificant Bit)存储于最低内存地址处。

        主机字节序

不同的主机有不同的字节序,如x86为小端字节序,Motorola 6800为大端字节序,ARM字节序是可配置的。

     网络字节序规定为大端字节序

#include <stdio.h>  
#include <arpa/inet.h>  
int main(){  
  
                unsigned long a = 0x12345678;  
                unsigned char *p = (unsigned char *)(&a);  
  
                printf("主机字节序:%0x    %0x   %0x   %0x\n",  p[0], p[1], p[2], p[3]);  
  
                unsigned long b = htonl(a);  //将主机字节序转化成了网络字节序  
                  
                p = (unsigned char *)(&b);  
  
                printf("网络字节序:%0x    %0x   %0x   %0x\n",  p[0], p[1], p[2], p[3]);  
                return 0;  
        }

关于:htonl

[cpp]  view plain  copy
  1. #include <arpa/inet.h>  
  2.   
  3.        uint32_t htonl(uint32_t hostlong);  
  4.   
  5.        uint16_t htons(uint16_t hostshort);  
  6.   
  7.        uint32_t ntohl(uint32_t netlong);  
  8.   
  9.        uint16_t ntohs(uint16_t netshort); 

h是主机host,n是网络net,l是长整形long,s是短整形short,所以上面这些函数还是很好理解的

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #include <arpa/inet.h>  
  3.   
  4. int main()  
  5. {  
  6.         struct in_addr ipaddr;  
  7.         unsigned long addr = inet_addr("192.168.1.100");  
  8.         printf("addr = %u\n", ntohl(addr));  
  9.   
  10.         ipaddr.s_addr = addr;  
  11.         printf("%s\n", inet_ntoa(ipaddr));        
  12.         return 0;         
运行结果:

值得注意的是:

in_addr_in   inet_addr(const char *strptr);

inet_addr的参数是一个:点分十进制字符串,返回的值为一个32位的二进制网络字节序的IPv4地址,不然的话就是:INADDR_NONE

而返回值为:in_addr_t:IPv4,一般为uint32_t

所以也可以定义为:unsigned long


char * inet_ntoa(struct in_addr inaddr);

参数是一个结构体,所以要调用必须先定义一个结构体。

字节序转换函数

  uint32_t htonl(uint32_t hostlong);

  uint16_t htons(uint16_t hostshort);

  uint32_t ntohl(uint32_t netlong);

  uint16_t ntohs(uint16_t netshort);

  说明:在上述的函数中,h代表host;n代表network s代表short;l代表long

 

地址转换函数

  #include <netinet/in.h>

  #include <arpa/inet.h>

  int inet_aton(const char *cp, struct in_addr *inp);

  in_addr_t inet_addr(const char *cp);

  char *inet_ntoa(struct in_addr in);


猜你喜欢

转载自blog.csdn.net/coolwriter/article/details/80299293