Обнаружение любой подключенной сети

Как я могу определить, подключен ли какой-либо сетевой адаптер? Я могу найти только примеры использования NSReachability для обнаружения подключения к Интернету, но я хочу обнаружить даже подключение к сети без подключения к Интернету. Получение IP-адреса на eth0 должно работать? Я работаю только на Mac.


person Andreas Bergström    schedule 02.10.2012    source источник
comment
Вы работаете на iOS, Mac или на обоих?   -  person Bryan    schedule 08.10.2012
comment
Хорошо, я пробовал это только на iPhone, поэтому мой ответ может не работать на Mac. Я посмотрю, смогу ли я провести еще несколько исследований.   -  person Bryan    schedule 09.10.2012
comment
Это было бы очень признательно.   -  person Andreas Bergström    schedule 09.10.2012
comment
Вы не должны полагаться на определенные имена интерфейсов, такие как eth0. На iMac en0 может быть (неподключенным) интерфейсом Ethernet, а en1 — (подключенным) интерфейсом WiFi. Mac Pro может иметь 2 интерфейса Ethernet en0 и en1.   -  person Martin R    schedule 15.10.2012


Ответы (3)


Получение Список всех IP-адресов в Техническом примечании Apple TN1145 упоминает 3 метода получения статуса сетевых интерфейсов:

  • Структура конфигурации системы
  • Открытый транспортный API
  • BSD-сокеты

Структура конфигурации системы: это рекомендуемый Apple способ, и в TN1145 есть пример кода. Преимущество заключается в том, что он предоставляет способ получать уведомления об изменениях в конфигурации интерфейса.

Открытый транспортный API: в TN1145 также есть пример кода, иначе я не могу много о нем сказать. (На веб-сайте Apple есть только «устаревшая» документация.)

Сокеты BSD: кажется, что это самый простой способ получить список интерфейсов и определить статус подключения (если вам не нужны уведомления о динамических изменениях).

В следующем коде показано, как найти все интерфейсы IPv4 и IPv6, которые «запущены и работают».

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <netdb.h>

struct ifaddrs *allInterfaces;

// Get list of all interfaces on the local machine:
if (getifaddrs(&allInterfaces) == 0) {
    struct ifaddrs *interface;

    // For each interface ...
    for (interface = allInterfaces; interface != NULL; interface = interface->ifa_next) {
        unsigned int flags = interface->ifa_flags;
        struct sockaddr *addr = interface->ifa_addr;

        // Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
        if ((flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING)) {
            if (addr->sa_family == AF_INET || addr->sa_family == AF_INET6) {

                // Convert interface address to a human readable string:
                char host[NI_MAXHOST];
                getnameinfo(addr, addr->sa_len, host, sizeof(host), NULL, 0, NI_NUMERICHOST);

                printf("interface:%s, address:%s\n", interface->ifa_name, host);
            }
        }
    }

    freeifaddrs(allInterfaces);
}
person Martin R    schedule 14.10.2012
comment
Большое спасибо, лучший ответ на данный момент. У меня нет времени попробовать это прямо сейчас, но если в ближайшие 6 часов не выйдет что-то лучшее, я соглашусь. - person Andreas Bergström; 15.10.2012
comment
@AndreasBergström: Это нормально. Я рад, если это помогло. - person Martin R; 15.10.2012

Вы можете использовать код Reachability, предоставленный Apple. Вот ссылка, по которой можно получить "Доступность " исходный код:

Вы также можете скачать этот файл: TestWifi в Github. Он покажет вам, как реализовать класс Reachability.

Надеюсь, это поможет вам.


person angelmacaraig    schedule 11.10.2012
comment
Предоставленная вами ссылка доступности предназначена для iOS. - person Mick MacCallum; 13.10.2012

Reachability (я полагаю, вы имели в виду демонстрационный класс Apple, основанный на базовом SCNetworkReachability... API) работает для любого хоста, подключенного к IP, в том числе в вашей локальной сети. Вы можете использовать метод reachabilityForLocalWiFi, хотя, согласно этой странице, он вернет YES, когда сеть активный, но не маршрутизируемый. Поэтому вы можете запросить reachabilityWithAddress: с локальным адресом.

Это замена Reachability, которую некоторые рекомендуют.

person Bryan    schedule 08.10.2012