c++ - 在 C++ 中获取本地 IP 地址

标签 c++ ip

我有一个获取本地 ip 地址的代码。这是我使用的代码。

typedef std::map<string,string> settings_t;

void loadLocalIp (settings_t &ipConfig)
{
    struct ifaddrs * ifAddrStruct=NULL;
    struct ifaddrs * ifa=NULL;
    void * tmpAddrPtr=NULL;      

    getifaddrs(&ifAddrStruct);

    for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
        if (ifa ->ifa_addr->sa_family==AF_INET) { // check it is IP4
            // is a valid IP4 Address
            tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
            char addressBuffer[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);

            string key(ifa->ifa_name);
            string value(addressBuffer);
            cout<<key<<" =1 " <<value<<endl;
            ipConfig.insert(std::pair<string,string>(key, value));

           // printf("'%s': %s\n", ifa->ifa_name, addressBuffer); 
         }
     }
    if (ifAddrStruct!=NULL) 
        freeifaddrs(ifAddrStruct);//remember to free ifAddrStruct
}

int main()
{
    settings_t ipConfig;
    loadLocalIp(ipConfig);
    cout<<ipConfig.at("enp2s0")<<endl;
    return 0;
}

所以我的结果是

lo =1 127.0.0.1
enp2s0 =1 172.20.55.6
172.20.55.6

但是在另一台电脑上,接口(interface)名称是不同的。他们得到如下结果,

lo =1 127.0.0.1
ens32 =1 172.20.55.9
terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at
Aborted (core dumped)

无论接口(interface)名称是什么,我都想获取我的 IP 地址。如果接口(interface)名称因不同计算机而异,如何获取本地 IP 地址。无论接口(interface)名称是什么,它都应该给出 ip 地址。我该怎么做?

我的问题是,现在我正在通过这种方法获取我的本地 IP。但无论接口(interface)名称是什么,我都应该获得 IP。一件事,我需要找到该接口(interface)名称并将其应用到我上面的代码中(或者)是否有其他选项可以在没有该接口(interface)的情况下找到该 IP?

最佳答案

I want to get my IP address whatever the interface name is.

通过查看网络接口(interface)很难可靠地获取本地 ip 地址。正如您已经发现的那样,网络接口(interface)名称对于您运行的每个主机来说都是唯一的。更复杂的是,一台计算机可能有多个网络接口(interface),每个接口(interface)都可能连接到互联网,也可能不连接到互联网。

您不需要使用默认界面。一种更简单的方法是让操作系统路由表为您解决。您可以通过设置到某个外部服务器的套接字连接然后调用 getsockname 来完成此操作。获取本地地址。此示例使用位于 8.8.8.8 的 Google DNS 服务器建立套接字连接,但您可以使用您喜欢的任何外部服务器。

#include <iostream>     ///< cout
#include <cstring>      ///< memset
#include <errno.h>      ///< errno
#include <sys/socket.h> ///< socket
#include <netinet/in.h> ///< sockaddr_in
#include <arpa/inet.h>  ///< getsockname
#include <unistd.h>     ///< close

int main()
{
    const char* google_dns_server = "8.8.8.8";
    int dns_port = 53;

    struct sockaddr_in serv;
    int sock = socket(AF_INET, SOCK_DGRAM, 0);

    //Socket could not be created
    if(sock < 0)
    {
        std::cout << "Socket error" << std::endl;
    }

    memset(&serv, 0, sizeof(serv));
    serv.sin_family = AF_INET;
    serv.sin_addr.s_addr = inet_addr(google_dns_server);
    serv.sin_port = htons(dns_port);

    int err = connect(sock, (const struct sockaddr*)&serv, sizeof(serv));
    if (err < 0)
    {
        std::cout << "Error number: " << errno
            << ". Error message: " << strerror(errno) << std::endl;
    }

    struct sockaddr_in name;
    socklen_t namelen = sizeof(name);
    err = getsockname(sock, (struct sockaddr*)&name, &namelen);

    char buffer[80];
    const char* p = inet_ntop(AF_INET, &name.sin_addr, buffer, 80);
    if(p != NULL)
    {
        std::cout << "Local IP address is: " << buffer << std::endl;
    }
    else
    {
        std::cout << "Error number: " << errno
            << ". Error message: " << strerror(errno) << std::endl;
    }

    close(sock);
    return 0;
}

关于c++ - 在 C++ 中获取本地 IP 地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49335001/

相关文章:

c++ - 将 char 数组中的数值存储到 VC++ 中的 INTEGER 变量中。

安卓获取外网IP

java 。 InetAddress.getLocalHost 返回奇怪的 IP

java - 通过 Java 获取 EC2 实例的 instance-id

iOS: session +改变IP地址;如何在客户端处理它?

c++ - 如何在 C++ 中向字符串添加多个项目?

c++ - STL map 不会删除

c++ - 相机同步

c++ - const_cast 比普通 Actor 更安全吗?

java - 如何显示特定接口(interface)的 IP 地址?