2010-01-27 381 views
15

我试图使用getaddrinfo()函数获取我的本地(而不是外部)IP地址,但我看到提供的示例here,它们对于我的需求太复杂。还看到其他帖子,其中大多数真的想获得外部IP,而不是本地IP。使用getaddrinfo()C函数获取本地IP地址?

任何人都可以提供一个简单的例子(或一个简单的例子)有关如何获得我自己的本地IP地址使用此功能的链接?

只是说清楚当我说本地,如果路由器是192.168.0.1,我的本地IP地址可能是类似192.168.0.x(只是一个例子)。

+0

的getaddrinfo是为了有一个ipv4和ipv6之间的统一接口,这就是为什么它看起来有点复杂。 (如果得到答案,我会在稍后让你知道) – Aif 2010-01-27 10:59:37

+0

谢谢! ,是的,它看起来很复杂,我不想使用gethostbyname(),因为它似乎被弃用... – Goles 2010-01-27 11:03:32

+1

该页面的最后一个例子是如何做到这一点...为什么这太复杂?如果你真的只需要一个IPv4地址,那么使用AF_INET ......但是不要那样做,也要支持IPv6。 – 2010-01-27 11:30:38

回答

32

getaddrinfo()不用于获取您的本地IP地址 - 它用于查找名称和/或服务到套接字地址。为了获得本地IP地址(ES),你想要的功能是getifaddrs() - 这里有一个小例子:

#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <net/if.h> 
#include <ifaddrs.h> 
#include <errno.h> 

int main(int argc, char *argv[]) 
{ 
    struct ifaddrs *myaddrs, *ifa; 
    void *in_addr; 
    char buf[64]; 

    if(getifaddrs(&myaddrs) != 0) 
    { 
     perror("getifaddrs"); 
     exit(1); 
    } 

    for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) 
    { 
     if (ifa->ifa_addr == NULL) 
      continue; 
     if (!(ifa->ifa_flags & IFF_UP)) 
      continue; 

     switch (ifa->ifa_addr->sa_family) 
     { 
      case AF_INET: 
      { 
       struct sockaddr_in *s4 = (struct sockaddr_in *)ifa->ifa_addr; 
       in_addr = &s4->sin_addr; 
       break; 
      } 

      case AF_INET6: 
      { 
       struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)ifa->ifa_addr; 
       in_addr = &s6->sin6_addr; 
       break; 
      } 

      default: 
       continue; 
     } 

     if (!inet_ntop(ifa->ifa_addr->sa_family, in_addr, buf, sizeof(buf))) 
     { 
      printf("%s: inet_ntop failed!\n", ifa->ifa_name); 
     } 
     else 
     { 
      printf("%s: %s\n", ifa->ifa_name, buf); 
     } 
    } 

    freeifaddrs(myaddrs); 
    return 0; 
} 
+0

感谢这个概念证明,我认为它非常清楚。 – Goles 2010-01-29 09:46:45

+1

这是我见过的最好的答案。 – xmllmx 2013-03-20 15:48:34

+0

'getaddrinfo()'当然可以用来获取本地IP地址。请参阅http://beej.us/guide/bgnet/output/html/multipage/syscalls.html#getaddrinfo。它也具有更便携的好处 - 'getifaddrs()'大多局限于Linux。 – patrickvacek 2014-03-21 14:18:17

-1

传递主机名使用gethostname()后,以gethostbyname()

int gethostname(char *hostname, size_t size); 
+0

不,主机名可能无法解析。试图解决它是不好的。这是一个常见的编程错误,所以有些系统保证通过返回“127.0.1.1”来解析主机名,这样就没有错误。因此,你甚至不能依靠回报,因为它可能不是一个有用的地址。 – 2013-08-23 15:51:09