получить IP-адрес локальной сети и распечатать его - PullRequest
1 голос
/ 11 января 2011

Кто-нибудь знает, как я могу получить свой IP-адрес локальной сети и распечатать его на экране. * Я имею в виду не оболочку, а программирование на с. ** Я буду признателен, если вы отправите мне пример кода.

Ответы [ 3 ]

4 голосов
/ 11 января 2011

Есть несколько подходов;во-первых, вы можете установить соединение с известным узлом, используя connect(2), а затем прочитать имя локального сокета с помощью getsockname(2).Это довольно слабый механизм, но он прост.

Но getsockname(2) будет сообщать только один IP-адрес, когда у машины может быть тысячи IP-адресов и какой IP-адресВозвращение будет зависеть отчасти от выбранного вами партнера!Итак, не очень надежный.

Гораздо лучший ответ - использовать rtnetlink(7) для считывания IP-адресов машины непосредственно из ядра: вы бы отправляли в ядро ​​сообщения RTM_GETADDR для каждого интерфейса намашинка и читай ответы обратно.Лучше всего понять, как использовать это, вероятно, прочитав исходный код программы ip.

Другой вариант - использовать SIOCGIFCONF ioctl(2) на сокете IP.Этот интерфейс не такой гибкий, как интерфейс rtnetlink(7), поэтому он не всегда может быть правильным, но это будет промежуточная точка.Утилита ifconfig(8) использует этот подход для отображения вывода ifconfig -a.Опять же, вам лучше всего прочитать исходный текст.(Есть небольшая документация в ioctl_list(2).)

3 голосов
/ 12 января 2011

Функция getifaddrs() из <ifaddrs.h> - это самый простой способ получить текущие интерфейсы и соответствующие адреса:

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

int main()
{
    struct ifaddrs *iflist, *iface;

    if (getifaddrs(&iflist) < 0) {
        perror("getifaddrs");
        return 1;
    }

    for (iface = iflist; iface; iface = iface->ifa_next) {
        int af = iface->ifa_addr->sa_family;
        const void *addr;
        char addrp[INET6_ADDRSTRLEN];

        switch (af) {
            case AF_INET:
                addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr;
                break;
            case AF_INET6:
                addr = &((struct sockaddr_in6 *)iface->ifa_addr)->sin6_addr;
                break;
            default:
                addr = NULL;
        }

        if (addr) {
            if (inet_ntop(af, addr, addrp, sizeof addrp) == NULL) {
                perror("inet_ntop");
                continue;
            }

            printf("Interface %s has address %s\n", iface->ifa_name, addrp);
        }
    }

    freeifaddrs(iflist);
    return 0;
}
2 голосов
/ 11 января 2011

gethostbyname должен помочь вам сделать это.Пример:

GetLocalAddress()
{
  char ac[80];

  // Get my host name
  if (gethostname(ac, sizeof(ac)) != -1)
  {
    printf("Host name: %s\n", ac);

    // Find IP addresses
    struct hostent* p_he = gethostbyname(ac);

    if (p_he != 0)
    {
        for (int i=0; p_he->h_addr_list[i] != 0; ++i)
        {
            struct in_addr addr;
            memcpy(&addr, p_he->h_addr_list[i], sizeof(struct in_addr));
            printf("IP address %d: %s\n", i, inet_ntoa(addr));
        }
    }
}

Возможно, вы захотите отфильтровать, чтобы удалить 127.0.0.1 из списка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...