如何在C ++中将IP地址(包括ipv4和ipv6)转换为二进制?

时间:2013-03-20 18:05:20

标签: c++ ip

我有一个代表ip地址的字符串,它可以是ipv4和ipv6。

我想要的是将它转换为十进制形式,然后我可以从中获得单个位。

例如,对于字符串“192.168.0.1”表示的地址,我想得到一个小数3232235521.。

最好的方法是使用一些标准库,例如函数inet_pton会很棒。但我无法理解如何使用它。

我根据有关sockaddr_in here的信息编写了以下代码:

   struct sockaddr_in sa;
   char str[INET_ADDRSTRLEN];
   // store this IP address in sa:
   inet_pton(AF_INET, "192.168.0.1", &(sa.sin_addr));
   cout<<"bin by inet_pton"<<sa.sin_addr.s_addr<<endl;

这给了我553779392.这个数字对应于1.0.168.192。当然,我可以编写一些函数以某种方式反转这个数字,但我正在寻找一些将ip地址转换为二进制的标准有效方法。

3 个答案:

答案 0 :(得分:2)

我从Beej的网络编程指南中抽取了这段代码:

struct sockaddr_in antelope;
char *some_addr;

inet_aton("10.0.0.1", &antelope.sin_addr); // store IP in antelope

some_addr = inet_ntoa(antelope.sin_addr); // return the IP
printf("%s\n", some_addr); // prints "10.0.0.1"

// and this call is the same as the inet_aton() call, above:
antelope.sin_addr.s_addr = inet_addr("10.0.0.1");

我们这里有一个在通常用于存储地址信息的结构类型和字符串之间来回移动ip地址的示例。这段代码的最后一行基本上就是你需要的。 ip地址的整数表示存储在antelope.sin_addr.s_addr中。 s_addr只是一个unsigned long,所以它应该是你需要的。如果你这样做:

cout << antelope.sin_addr.s_addr << endl;

你会得到10.0.0.1的十进制表示

编辑:我在您的原始代码下添加了一条评论来表达您已经拥有的代码的问题,这基本上只是一个endianness的问题。我在这个答案中给你的代码可能会给你同样的问题。您需要使用htonl()来反转字节顺序。

答案 1 :(得分:1)

用于检索IP地址的 INTEGER 表示形式:

我们需要密切关注@ 2to1mux帖子中的以下信息。

ip地址的整数表示形式存储在antelope.sin_addr.s_addr中。

s_addr只是一个无符号长

示例:

struct sockaddr_in antelope;

// Here I had to convert from NSString to c string
inet_pton(AF_INET, [ipAddress UTF8String], &(antelope.sin_addr));

// This line gets the integer value
UInt32 address = antelope.sin_addr.s_addr;

我希望这篇额外的帖子让我感到困惑,就像我一样。

答案 2 :(得分:0)

来到这里,寻找一个优雅的解决方案来测试一个 IP 地址是否在给定的 IP 地址对之间。 这是我在@2to1mux 的解决方案上花费的 2 美分。只需将它们放在一起,以防有人需要一个完整的示例。这可以修改为处理 IPV6 吗?

    #include <arpa/inet.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
           
    size_t ip_to_num(int family, char *IP)
    {
        size_t i = 0;
        struct sockaddr_in antelope;
        inet_pton(family, IP, &(antelope.sin_addr));
        i = ntohl(antelope.sin_addr.s_addr);
        
        return i;
    }
    
   
    void print_num_to_ip(int family, size_t i)
    {
        /* This structure is actually not required here.
            Added just to show how numbers can be transformed into valid socket structures.
        */        
        struct sockaddr_in antelope; 
    
        memset(&antelope, 0, sizeof(antelope));
        antelope.sin_family = family;
        antelope.sin_port = htons(0);
    
        antelope.sin_addr.s_addr = htonl(i);
        printf("IP: %zu [%s] \n", i, inet_ntoa(antelope.sin_addr));    
    }
    
    int main ()
    {
        char IP[INET6_ADDRSTRLEN]="192.168.0.2";
        size_t x = 0;
        
        x = ip_to_num(AF_INET, IP);
        
        printf("IP: %zu [%s] \n", x, IP);
        
        print_num_to_ip(AF_INET, x);
        
        exit(EXIT_SUCCESS);
    }