IP地址在很多嵌入式系统中都会存储为一个32位的int数,因为它每一段都恰好可以用4组8位二进制表示,如果用字符串表示会浪费空间。
这就涉及到了IP地址和int数的互相转换,其实原理相当简单,如下:
IP:192.168.1.1
1 拆分:【192】【168】【1】【1】
2 每段都变为8位的二进制:【11000000】【10101000】【00000001】【00000001】
3 合成一个数:11000000101010000000000100000001=3232235777
组合成一个数最简单的方式就是用移位和或运算:
用p1 p2 p3 p4代替ip四段数据
p1<<(3*8) 第一段左移3个8位即24位
p2<<(2*8)第二段左移16位
p3<<8 第三段左移8位
p4不变
移位后数据后面都填充0,四段数据相加其实就是或,所以p1|p2|p3|p4后就是ip地址转换成的整数
把整数转换成ip的过程正好是反过来:
1 p1=value&0xff000000//取第一段8位数
2 p1>>(3*8)//右移去掉后面的0,变成正确的整数
p2 = (value & 0x00ff0000)>>(2*8);
p3 = (value & 0x0000ff00)>>(8);
p4 = (value & 0x000000ff);
3 然后把每段都变成字符串连接起来,中间添加分隔符[.]就成了ip地址。
example:
1 void IP2Int(char* ip) 2 { 3 unsigned int intip= 0; 4 unsigned int p1=0; 5 unsigned int p2 =0; 6 unsigned int p3 =0; 7 unsigned int p4 =0; 8 9 char* tmp=NULL; 10 11 tmp = strtok(ip,"."); 12 p1 = atoi(tmp); 13 14 tmp = strtok(NULL,"."); 15 p2 = atoi(tmp); 16 17 tmp = strtok(NULL,"."); 18 p3 = atoi(tmp); 19 20 tmp = strtok(NULL,"."); 21 p4 = atoi(tmp); 22 23 intip = (p1<<(3*8)) | (p2<<(2*8)) | (p3<<8) | p4;//use + result is 0,why ? 24 } 25 26 void Int2IP(unsigned int value) 27 { 28 char ip[16]= {0}; 29 unsigned char p1=0; 30 unsigned char p2 =0; 31 unsigned char p3 =0; 32 unsigned char p4 =0; 33 34 p1 = (value & 0xff000000)>>(3*8); 35 36 p2 = (value & 0x00ff0000)>>(2*8); 37 38 p3 = (value & 0x0000ff00)>>(8); 39 40 p4 = (value & 0x000000ff); 41 42 snprintf(ip,sizeof(ip),"%d.%d.%d.%d",p1,p2,p3,p4); 43 }