大端小端转换问题
终端中获得的点分十进制形式的ip地址,ip地址在网络中以大端格式传输,本地存储的是以小端格式。
`ping www.baidu.com`获得的ip为`58.217.200.15`
终端中获得的点分十进制形式的ip地址,ip地址在网络中以大端格式传输,本地存储的是以小端格式。
`ping www.baidu.com`获得的ip为`58.217.200.15`
该地址的十六进制(本地小端存储)为`3ad9c80f`,在网络中传输地址为`0fc8d93a`.
1.将点分十进制地址转换为网络地址
int ip_aton(char* ip_addr) {
int buf[4];
memset(buf, 0, 16);
sscanf(ip_addr, "%d.%d.%d.%d", &buf[0], &buf[1], &buf[2], &buf[3]);
int index = 0, result = 0;
for (index = 0; index < 4; ++index) {
result |= (buf[index] &0xff);
if (index < 3) {
result = result << 8;
}
}
return result;
}
2.将网络地址转换为点分十进制地址(字符串ip_addr接收此地值)
void ip_ntoa(int ip, char *ip_addr) {
int len = strlen(ip_addr);
int index;
memset(ip_addr, 0, len);
int a[4];
for (index = 0; index < 4; ++index) {
a[index] = (int)(ip & 0xff);
ip = ip >> 8;
}
sprintf(ip_addr, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
}
3.大端存储小端存储之间的相互转换
int reverse(int src)
{
int b ;
b = ((src & 0xff) << 24)|((src & 0xff000000)>>24)| \
(( src & 0xff00) <<8)|((src & 0xff0000)>>8);
return b ;
}
4.判断本机编译器是大端模式还是小端模式
//方法1
void test() {
short int x;
char x0, x1;
x = 0x1122;
x0 = ((char*)&x)[0];//将数组指针强制转换为字符指针取第0个元素
x1 = ((char*)&x)[1];
if (0x11 == x0) {
printf("大端存储\n");
} else {
printf("小端存储\n");
}
}
//方法2:取一个ip地址,使用int inet_aton(const char *cp, struct in_addr *inp),根据打印结果和ip地址比较
oid test2() {
char ip[] = "58.217.200.15";
struct in_addr myaddr;
inet_aton(ip, &myaddr);
printf("%08x\n", myaddr.s_addr);
}
打印结果为:`0fc8d93a`,你可以考虑ip`58.217.200.15`正常的网络字节序应该为‘3ad9c80f’。所以打印结果和网络字节序位置颠倒,所以为小端存储。