2010-01-27 45 views
15

Tôi đang cố gắng lấy địa chỉ IP cục bộ (không phải bên ngoài) bằng hàm getaddrinfo(), nhưng tôi thấy các ví dụ được cung cấp here và chúng quá phức tạp cho nhu cầu của tôi. Cũng thấy các bài viết khác và hầu hết trong số họ thực sự muốn có được IP bên ngoài, không phải là địa phương.Lấy địa chỉ IP cục bộ bằng hàm getaddrinfo() C?

Có ai có thể cung cấp liên kết đến một ví dụ đơn giản (hoặc một ví dụ đơn giản) về cách lấy địa chỉ IP cục bộ của riêng tôi bằng cách sử dụng chức năng này không?

Chỉ cần rõ ràng khi tôi nói cục bộ, nếu bộ định tuyến là 192.168.0.1, địa chỉ IP cục bộ của tôi có thể giống như 192.168.0.x (chỉ là một ví dụ).

+0

getaddrinfo đã được thực hiện để có một giao diện thống nhất giữa ipv4 và ipv6, đây là lý do tại sao nó trông hơi phức tạp. (Nếu nhận được câu trả lời, tôi sẽ cho bạn biết sau) – Aif

+0

Cảm ơn! , có, có vẻ phức tạp và tôi không muốn sử dụng gethostbyname() vì nó có vẻ không được chấp nhận ... – Goles

+1

Ví dụ cuối cùng trên trang đó là cách thực hiện điều này ... tại sao quá phức tạp? Sử dụng AF_INET nếu bạn thực sự chỉ muốn có một địa chỉ IPv4 ... nhưng không làm điều đó, làm cho nó hỗ trợ IPv6 là tốt. –

Trả lời

32

getaddrinfo() không phải là để lấy địa chỉ IP cục bộ của bạn - đó là tìm kiếm tên và/hoặc dịch vụ đến địa chỉ ổ cắm. Để có được địa chỉ IP cục bộ (es), chức năng bạn muốn là getifaddrs() - đây là một ví dụ nhỏ:

#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

Cảm ơn bằng chứng về khái niệm này, tôi nghĩ nó rất rõ ràng. – Goles

+1

Đây là câu trả lời hay nhất mà tôi từng thấy trong câu hỏi này. – xmllmx

+0

'getaddrinfo()' chắc chắn có thể được sử dụng để lấy địa chỉ IP cục bộ. Xem http://beej.us/guide/bgnet/output/html/multipage/syscalls.html#getaddrinfo. Nó cũng có lợi ích của việc di chuyển nhiều hơn - 'getifaddrs()' chủ yếu được giới hạn trong Linux. – patrickvacek

-1

Vượt qua hostname sau khi sử dụng gethostname(), để gethostbyname()

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

Không, tên máy chủ có thể không giải quyết được. Nó không tốt để cố gắng giải quyết nó. Đó là một lỗi lập trình phổ biến mặc dù, do đó, một số hệ thống đảm bảo rằng tên máy chủ có thể phân giải bằng cách trả về "127.0.1.1" chỉ để không có lỗi. Vì vậy, bạn thậm chí không thể dựa vào sự trở lại bởi vì nó có thể thậm chí không phải là một địa chỉ hữu ích. –

Các vấn đề liên quan