在 C++ Linux 中获取本地 IP 地址

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4130147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:54:07  来源:igfitidea点击:

Get local IP address in C++ Linux

c++linux

提问by Leslieg

I needed to find the IP address for the local machine on of the webservices. In C#, I have

我需要在 Web 服务上找到本地机器的 IP 地址。在 C# 中,我有

ManagementObjectSearcher objC = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = 'TRUE'");
ManagementObjectCollection objCollection = objC.Get();

How could I do it in C++ Linux?

我怎么能在 C++ Linux 中做到这一点?

回答by Duck

getifaddrs()will return a list of structures of all the interfaces in the machine. There is an example at the bottom of the man page.

getifaddrs()将返回机器中所有接口的结构列表。手册页底部有一个示例。

You can also use ioctl with the SIOCGIFCONF parameter. There is an example here

您还可以将 ioctl 与 SIOCGIFCONF 参数一起使用。有一个例子在这里

回答by Joshua

My favorite way:

我最喜欢的方式:

  1. Make a UDP socket
  2. Bind to wildcard
  3. Connect to 1.2.3.41.1.1.1
  4. getsockname
  1. 创建一个 UDP 套接字
  2. 绑定到通配符
  3. 连接到1.2.3.41.1.1.1
  4. 获取名称

1.2.3.4 isan impossible IP address that happens to be treated by all hosts as outobund. 1.1.1.1 is CloudFlare's DNS server with multicast routing so your host can't be it. (If they ever make 1. allocatable you will have to use 0.2.3.4 which can potentially invoke undefined behavior).

1.2.3.4一个不可能的 IP 地址,恰好被所有主机视为外流。1.1.1.1 是 CloudFlare 的具有多播路由的 DNS 服务器,因此您的主机不能成为它。(如果他们使 1. allocatable 你将不得不使用 0.2.3.4 这可能会调用未定义的行为)。

You will need to update this for IPv6 of course.

当然,您需要针对 IPv6 更新此内容。

回答by Bradley Kreider

Your specific question is answered in the following pages:

您的具体问题在以下页面中得到解答:

But here is more information about BSD sockets. Beej's Guide to Network Programmingis a good place to learn more.

但这里有更多关于 BSD 套接字的信息。 Beej 的网络编程指南是了解更多信息的好地方。

回答by mahi

C++ in linux using the system call 'getifaddr' to get all interface of your network card. Here are two function and a struct you need.

Linux 中的 C++ 使用系统调用“getifaddr”来获取网卡的所有接口。这是您需要的两个函数和一个结构。

struct ifaddrs{
    struct ifaddrs *ifa_next;   /* Pointer to the next structure.  */
    char *ifa_name;     /* Name of this network interface.  */
    struct sockaddr *ifa_addr;  /* Network address of this interface.  */
    ...
}
int getifaddrs(struct ifaddrs **ifap); //to get all interface config fed to ifap
void freeifaddrs(struct ifaddrs *ifa); //to free ifa

And here is an example provided by user Twelve47at Get the IP address of the machineto get IPv4 and IPv6 address of all interfaces:

这是用户Twelve47获取机器的 IP 地址以获取所有接口的 IPv4 和 IPv6 地址时提供的示例:

#include <stdio.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h> 
#include <string.h> 
#include <arpa/inet.h>

int main (int argc, const char * argv[]) {
    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);
            printf("'%s': %s\n", ifa->ifa_name, addressBuffer); 
         } else if (ifa->ifa_addr->sa_family==AF_INET6) { // check it is IP6
            // is a valid IP6 Address
            tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
            char addressBuffer[INET6_ADDRSTRLEN];
            inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN);
            printf("'%s': %s\n", ifa->ifa_name, addressBuffer); 
        } 
    }
    if (ifAddrStruct!=NULL) 
        freeifaddrs(ifAddrStruct);//remember to free ifAddrStruct
    return 0;
}