1.大端序和小端序
大端序(Big Endian):高位字节存放到低位地址;
小端序(Little Endian):高位字节存放到高位地址;
整数0x12345678采用大端序存储:
采用小端序存储:
主机字节序(Host Byte Order):CPU的数据保存方式;主流Intel系列的CPU一般采用小端序方式;
网络字节序(Network Byte Order):由于不同的CPU的主机字节序可能不同,因此在通过网络传输数据时,约定统一用大端序方式;
借用别人总结的一句话方便记忆: “自大的人眼高手低”
2.字节序转换函数
#include <arpa/inet.h>
/* h:host,主机字节序;
* n:network,网络字节序;
* s:short,2字节;一般用于端口号转换;
* l:long,4字节;一般用于IP地址转换;
*/
unsigned short htons(unsigned short);
unsigned short ntohs(unsigned short);
unsigned long htonl(unsigned long);
unsigned long ntohl(unsigned long);
/* 功能:将字符串形式的IP地址转换为网络字节序整数;
* 参数:string - 字符串形式的IP地址;
* 返回:成功时返回4字节的大端序整数,失败时(无效IP地址)返回INADDR_NONE;
*/
in_addr_t inet_addr(const char *string);
/* 功能:将字符串形式的IP地址转换为网络字节序整数;仅Linux中存在该函数;
* 参数:string - 字符串形式的IP地址;
* addr - sin_addr结构指针,保存转换结果;
* 返回:成功时返回1,失败时返回0;
*/
int inet_aton(const char *string, struct in_addr *addr);
/* 功能:将整数型IP地址转换为字符串形式的IP地址;
* 参数:addr - sin_addr结构;
* 返回:成功时返回转换后的字符串形式地址,失败时返回-1;
*/
char* inet_ntoa(struct in_addr addr);
3.字节序转换示例
#include <stdio.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
unsigned short host_port = 0x1234;
unsigned short network_port;
unsigned long host_ip = 0x12345678;
unsigned long network_ip;
network_port = htons(host_port);
network_ip = htonl(host_ip);
printf("host_port = %#x\n", host_port);
printf("network_port = %#x\n", network_port);
printf("host_ip = %#x\n", host_ip);
printf("network_ip = %#x\n", network_ip);
return 0;
}
在我的测试机器上执行,输出结果如下: