在裘宗燕翻译的《程序设计实践》里,这对术语并没有翻译为“大端”和小端,而是“高尾端”和“低尾端”,这就好理解了:如果把一个数看成一个字符串,比如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
- #include <arpa/inet.h>
- 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是网络net,l是长整形long,s是短整形short,所以上面这些函数还是很好理解的
- #include <stdio.h>
- #include <arpa/inet.h>
- int main()
- {
- struct in_addr ipaddr;
- unsigned long addr = inet_addr("192.168.1.100");
- printf("addr = %u\n", ntohl(addr));
- ipaddr.s_addr = addr;
- printf("%s\n", inet_ntoa(ipaddr));
- 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); |