IPv4和IPv6地址的存取
存入IP地址时,使用inet_pton函数将输入的十进制字符串转出二进制。取出IP时再使用inet_ptop函数将“二进制整数”转成“点分十进制整数”显示。这两个函数都在宏定义#include <arpa/inet.h>中
C文件,test_ip.c
1 #include <stdio.h> 2 #include <arpa/inet.h> 3 #include "test_ip.h" 4 5 int main(int argc,char **argv) 6 { 7 ipmsg_t ip_msg; 8 ipaddr_t ip_addr; 9 char IPdotdec[20]="192.168.1.1"; 10 inet_pton(AF_INET, IPdotdec, (void *)&ip_addr.ipv4);//字符串 ——> 网络字节流
11 printf("decimal : %s -> hexadecimal : 0x%x\n",IPdotdec,ip_addr.ipv4); 12 13 ip_addr.ipv4 = ntohl(ip_addr.ipv4); 14 printf("decimal : %s -> hexadecimal : 0x%x\n",IPdotdec,ip_addr.ipv4); 15 16 ip_addr.ipv4 = htonl(ip_addr.ipv4); 17 ip_msg.ip_addr.data = (uint8_t *)&(ip_addr.ipv4); 18 ip_msg.ip_addr.len = 4; 19 ip_msg.prefix_len = 32; 20 21 char ip_str[20]={0}; 22 inet_ntop(AF_INET, ip_msg.ip_addr.data, ip_str, INET_ADDRSTRLEN);//网络字节流 ——> 字符串
23 printf("%s\n",ip_str); 24 return 0; 25 }
test_ip.h文件用于放定义的结构体
1 #ifndef __TEST_IP_H__ 2 #define __TEST_IP_H__ 3 4 #include <stdio.h> 5 6 #define uint8_t unsigned char 7 #define uint32_t unsigned int 8 typedef struct _ipdata_s { 9 uint8_t len; 10 uint8_t *data; 11 } ipdata_t; 12 13 typedef struct _ipmsg_s 14 { 15 ipdata_t ip_addr; 16 uint32_t prefix_len; 17 }ipmsg_t; 18 19 typedef struct _ip_addr_s { 20 uint32_t ipv4; //ipv4地址有32位,uint32_t就够了 21 uint32_t ipv6[4]; //ipv6地址有128位,用数组存uint32_t*4 22 } ipaddr_t; 23 24 #endif
运行结果
$ gcc -o test_ip test_ip.c $ ./test_ip decimal : 192.168.1.1 -> hexadecimal : 0x101a8c0 decimal : 192.168.1.1 -> hexadecimal : 0xc0a80101 192.168.1.1
转换关系
十进制 | 192 | 168 | 1 | 1 |
二进制(32位) | 11000000 | 10101000 | 00000001 | 00000001 |
十六进制 | c0 | a8 | 1 | 1 |
IPv6地址的存取,test_ipv6.c
1 #include <stdio.h> 2 #include <arpa/inet.h> 3 #include "test_ip.h" 4 5 int main(int argc,char **argv) 6 { 7 ipmsg_t ip_msg; 8 ipaddr_t ip_addr; 9 char IPdotdec[46]="2017::192:168:11:1"; 10 inet_pton(AF_INET6, IPdotdec, (void *)&ip_addr.ipv6);//字符串 ——> 网络字节流
11 printf("十六进制 : %s \n",IPdotdec); 12 printf("十进制 : %u %u %u %u\n", ip_addr.ipv6[0], ip_addr.ipv6[1], 13 ip_addr.ipv6[2], ip_addr.ipv6[3]); 14 15 16 ip_msg.ip_addr.data = (uint8_t *)&(ip_addr.ipv6[0]); 17 ip_msg.ip_addr.len = 16; 18 ip_msg.prefix_len = 128; 19 //ipv6的字符串:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
20 char ipv6_str[46]={0}; //最长是32(“x”)+7(“:”)=39个字节。定义46的数组就足够了
21 inet_ntop(AF_INET6, ip_msg.ip_addr.data, ipv6_str, INET6_ADDRSTRLEN);//网络字节流—>字符串
22 printf("%s\n",ipv6_str);
23 return 0;
24 }
运行结果
$ gcc -o test_ipv6 test_ipv6.c $ ./test_ipv6 十六进制 : 2017::192:168:11:1 十进制 : 5920 0 1744933377 16781568 2017::192:168:11:1
转换关系
十六进制 | 1720 | 0 | 0 | 0 | 6801 | 9201 | 0100 | 1100 |
二进制(128位) | 0001011100100000 | 0000000000000000 | 0000000000000000 | 0000000000000000 | 110100000000001 | 1001001000000001 | 0000000100000000 | 0001000100000000 |
十进制 | 5920 | 0 | 1744933377 | 16781568 |
参考:
IPV6 转换二进制:https://www.easycalculation.com/other/ipv6-to-binary.php