字符串中的 IP 地址检测 (C++)

Posted

技术标签:

【中文标题】字符串中的 IP 地址检测 (C++)【英文标题】:IP address detection in string (C++) 【发布时间】:2014-11-08 21:38:50 【问题描述】:

我对 C++ 中的 IP 地址检测有一个有趣的问题。我使用了inet_pton 函数和sockaddr_in 结构。如果字符串是有效的 IPv4 或 IPv6,函数将返回 AF_INETAF_INET6。否则返回零。

下面的代码不起作用。 SIGSEGV 在输入有效 IPv6 地址(IPv4 地址和无效地址都可以)时进行 IPv6 检测。删除 IPv4 条件后也有同样的问题。

#include <string>
#include <iostream>
#include <arpa/inet.h>

using namespace std;

int isIP(string);

int main(int argc, char *argv[])
        string s = "::1";
        int test = isIP(s);
        return 0;


int isIP(string addr)
        struct sockaddr_in sa;
        if((inet_pton(AF_INET, addr.c_str(), &(sa.sin_addr))))
                return AF_INET;
        if((inet_pton(AF_INET6, addr.c_str(), &(sa.sin_addr))))
                return AF_INET6;
        return 0;

但是当函数 IsIP 像下面的代码一样更改时,一切正常

int isIP(string addr)
        struct sockaddr_in sa;
        cout << addr + "\n";
        if(inet_pton(AF_INET, addr.c_str(), &(sa.sin_addr)))
                return AF_INET;
        if(inet_pton(AF_INET6, addr.c_str(), &(sa.sin_addr)))
                return AF_INET6;
        return 0;

int isIP(string addr)
        struct sockaddr_in sa, sa2;
        if((inet_pton(AF_INET, addr.c_str(), &(sa.sin_addr))))
                return AF_INET;
        if((inet_pton(AF_INET6, addr.c_str(), &(sa2.sin_addr))))
                return AF_INET6;
        return 0;

int isIP(string addr)
        struct sockaddr_in sa;
        int r1 = inet_pton(AF_INET, addr.c_str(), &(sa.sin_addr));
        int r2 = inet_pton(AF_INET6, addr.c_str(), &(sa.sin_addr));

        if(r1)
                return AF_INET;
        if(r2)
                return AF_INET6;
        return 0;

isIP 函数第一次实现的问题是什么?

【问题讨论】:

sockaddr_in6 大于 sockaddr_in 【参考方案1】:

在进行 ipv6 测试时,您必须将指针传递给 struct in6_addr。

【讨论】:

【参考方案2】:
struct sockaddr_in sa;

这是 IPv4 的结构;它没有足够的空间用于 IPv6 地址,因此在这些情况下您将超出范围。

向你的函数添加更多代码恰好为函数提供了更多内存——要么通过声明另一个变量,要么通过触发一些我们无法合理化的任意的、实现定义的构造——这样,当你溢出时sa,您正在溢出到进程拥有的内存中,因此不会触发访问冲突错误。但是,还是大错特错。

IPv6 地址将被读入struct in6_addr;一个包含在struct sockaddr_in6 中,例如:

bool isIPv6(const string& addr)

   struct sockaddr_in6 sa;
   if (inet_pton(AF_INET6, addr.c_str(), &(sa.sin_addr)))
       return true;
   return false;

【讨论】:

以上是关于字符串中的 IP 地址检测 (C++)的主要内容,如果未能解决你的问题,请参考以下文章

用C++如何将一个整数转换成一个IP地址?

检测IP地址的正则表达式

检测 C++ 字符流中的字符

C++ IP 地址人类可读的形式

如何在 C++ 中向字符串中添加字符?

C++:如何检测向量中的重复项并打印一份?