2010-01-27 16 views
15

Próbuję uzyskać mój lokalny (nie zewnętrzny) adres IP za pomocą funkcji getaddrinfo(), ale zobaczyłem przykłady dostarczone pod here, a one są zbyt złożone w stosunku do moich potrzeb. Widziałem także inne posty i większość z nich naprawdę chciała uzyskać zewnętrzny adres IP, a nie lokalny.Uzyskiwanie lokalnego adresu IP za pomocą funkcji getaddrinfo() C?

Czy ktoś mógłby podać link do prostego przykładu (lub prostego przykładu) o tym, jak uzyskać mój lokalny adres IP za pomocą tej funkcji?

Dla jasności, gdy mówię lokalnie, jeśli router jest 192.168.0.1, mój lokalny adres IP może być podobny do 192.168.0.x (tylko przykład).

+0

getaddrinfo powstał, aby mieć jednolity interfejs między ipv4 i ipv6, dlatego wygląda trochę skomplikowanie. (Jeśli otrzyma odpowiedź, poinformuję później) – Aif

+0

Dzięki! , tak, wygląda na skomplikowaną i nie chcę używać gethostbyname(), ponieważ wydaje się być przestarzałe ... – Goles

+1

Ostatni przykład na tej stronie jest jak to zrobić ... dlaczego to zbyt skomplikowane? Użyj AF_INET, jeśli naprawdę chcesz tylko adres IPv4 ... ale nie rób tego, spraw, aby wspierał również IPv6. –

Odpowiedz

32

getaddrinfo() nie służy do uzyskania lokalnego adresu IP - służy do wyszukiwania nazw i/lub usług na adresy gniazd. Aby uzyskać lokalny adres IP (ES), funkcja chcesz to getifaddrs() - oto minimalny przykład:

#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

Dziękuję za ten dowód koncepcji, myślę, że to jest bardzo jasne. – Goles

+1

To jest najlepsza odpowiedź, jaką kiedykolwiek widziałem na ten temat. – xmllmx

+0

'getaddrinfo()' można oczywiście użyć do uzyskania lokalnych adresów IP. Zobacz http://beej.us/guide/bgnet/output/html/multipage/syscalls.html#getaddrinfo. Ma także tę zaletę, że jest dużo bardziej przenośny - 'getifaddrs()' jest ograniczony głównie do Linuksa. – patrickvacek

-1

Przepuścić hosta po użyciu gethostname(), aby gethostbyname()

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

Nie, nazwa hosta może nie zostać rozstrzygnięta. Nie jest dobrze próbować go rozwiązać. Jest to powszechny błąd programistyczny, więc niektóre systemy gwarantują, że nazwa hosta jest możliwa do rozwiązania przez zwrócenie "127.0.1.1", tak aby nie wystąpił błąd. Dlatego nie możesz nawet polegać na zwrocie, ponieważ może to nawet nie być użyteczny adres. –

Powiązane problemy