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 }
02-11 02:52