1

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

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

例如,对于由字符串“192.168.0.1”表示的地址,我想得到一个十进制的 3232235521。

最好的办法是使用一些标准库,例如函数inet_pton会做得很好。但我不知道如何使用它。

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

   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 地址转换为二进制的标准且有效的方法。

4

3 回答 3

3

I yanked this code from Beej's Guide to Network Programming:

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");

What we have here is an example of moving an ip address back and forth between the type of struct which is generally used for storing address info and a string. The last line of this code is basically what you need. The integer representation of the ip address is being stored in antelope.sin_addr.s_addr. s_addr is just an unsigned long, so it should be exactly what you need. If you were to do this:

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

you would get the decimal representation of 10.0.0.1

EDIT: I added a comment under your original code to express the issue with the code that you already had, which is basically just an issue with endianness. The code I gave you in this answer might give you the same problem. You need to use htonl() to reverse the byte order.

于 2013-03-20T18:33:02.207 回答
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;

我希望这个额外的帖子能让像我这样的困惑者一目了然。

于 2014-04-23T16:37:57.310 回答
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);
    }
于 2021-05-27T12:17:49.753 回答