在裘宗燕翻译的《程序设计实践》里,这对术语并没有翻译为“大端”和小端,而是“高尾端”和“低尾端”,这就好理解了:如果把一个数看成一个字符串,比如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


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,所以上面这些函数还是很好理解的


1. #include <stdio.h>  
2. #include <arpa/inet.h>  
3.   
4. int main()  
5. {  
6. struct in_addr ipaddr;  
7. long addr = inet_addr("192.168.1.100");  
8. "addr = %u\n", ntohl(addr));  
9.   
10.         ipaddr.s_addr = addr;  
11. "%s\n", inet_ntoa(ipaddr));        
12. return 0;         
13. }


运行结果:

大端小端与网络字节序_#include_02

值得注意的是:

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);