Проверка частной сети на наличие локальных устройств с открытым определенным портом (iPhone / Objective C)

Я потратил целый день на создание системы между моим Mac и iPhone, в которой я использовал cocoaasyncsocket чтобы создать сервер прослушивания на моем Mac и клиент на моем iPhone. Основная идея состоит в том, чтобы оставить приложение на Mac работающим, пока компьютер включен, а затем, когда я хочу передать данные из приложения iPhone, запустить приложение, оно подключится и отправит данные ... У меня эта система работает точно как я хочу, чтобы он функционировал, но у меня есть 1 проблема, которую я пытался решить в общей сложности около 4 часов!

Я хотел создать что-то, что сканирует мою беспроводную сеть на предмет наличия моего Mac с запущенным слушателем ... Я думал, что это будет просто, но ошибался. Я искал все подряд, но безуспешно, и я использую stackoverflow в качестве последнего средства.

Мой текущий план состоял в том, чтобы «автоматически сканировать» путем получения внутреннего IP-адреса iPhone (например, 192.168.1.94), а затем использовать его, чтобы выяснить, каким будет другой IP-адрес в сети (192.168.1.0-254), теперь я знаю, какой IP-адрес для сканирования я могу пройтись по каждому из них и проверить, открыт ли порт / я получаю ответ.

Теперь я хочу сделать это как можно быстрее, однако я не смог получить НИЧЕГО, чтобы дать мне точные результаты ...

Использование connectToAddress:error: в cocoaasyncsocket просто вернет true для каждого из 255 различных IP-адресов, так же как и любые другие функции достижимости, с которыми я столкнулся ... Я читал, что это потому, что они проверяют только, получает ли соединение сделано и меня не волнует, что происходит на другом конце, поэтому мне нужно подумать о другом.

Мое единственное другое решение, которое я могу придумать, - это, возможно, проверить каждый внутренний IP-адрес и посмотреть, получу ли я ответ, но я не уверен, займет ли это слишком много времени, чтобы пройти через 255 IP-адресов ... а затем , как только я узнаю, какие IP-адреса активны, мне все равно нужно проверить, открыт ли порт как-то: /

Если кто-то здесь знает, как это можно сделать, или знает, как я могу проверить открытый порт (я не очень хорошо разбираюсь в сети), я был бы ОЧЕНЬ благодарен.

Спасибо за чтение,

Лиам


person liamnichols    schedule 20.07.2011    source источник


Ответы (2)


Я сам с этим не работал, но в основном Bonjour - это на самом деле то, что вы ищете, его цель - публикация и обнаружение сервисов.

person Harald Scheirich    schedule 20.07.2011
comment
Привет, спасибо за ответ ... Я должен был упомянуть, что в будущем у меня есть планы по созданию слушателя Windows, и я не заглядывал в Bonjour, так как не был уверен, смогу ли я работать с ним в Windows ... Я все равно буду изучать это, спасибо - person liamnichols; 21.07.2011
comment
IIRC есть версия Bonjour для Windows (я видел ее в обновлении для Apple Windows), но я не знаю, как они распространяют для нее исходники - person Harald Scheirich; 21.07.2011
comment
Спасибо за информацию ... Я думаю, что есть .net SDK для Windows, так что завтра я займусь этим. - person liamnichols; 21.07.2011

Хорошо, у меня сегодня была зарплата, и мне удалось заставить ее работать с помощью Bonjour!

Поскольку мне потребовалось время, чтобы во всем разобраться, я подумал, что помогу кому-нибудь еще ...

Во-первых, на стороне слушателя нам нужно настроить NSNetService, это можно сделать так:

    listenService = [[NSNetService alloc] initWithDomain:@"" type:@"_appname._tcp" name:@"Display Name" port:2427];
    [listenService setDelegate:self]; //make sure you include the NSNetServiceDelegate
    [listenService publish];

Затем вы можете подключиться к NSNetServiceDelegate, чтобы убедиться, что служба была успешно опубликована, и я использовал Bonjour Браузер, чтобы убедиться, что моя служба работает нормально (и это было так) ...

Затем на клиенте нам нужно найти службу с помощью [NSNetServiceBrowser] [3] ... Это можно сделать так:

    serviceBrowser = [[NSNetServiceBrowser alloc] init];
    [serviceBrowser setDelegate:self]; //remember to include NSNetServiceBrowserDelegate
    [serviceBrowser searchForServicesOfType:@"_appname._tcp" inDomain:@""];

Если вы затем включите методы NSNetServiceBrowserDelegate, вы можете прослушивать

netServiceBrowser:didFindService:moreComing:

Затем вы должны сохранить службу, предоставить ей делегата, а затем разрешить службу ... Затем, если вы прослушиваете NSNetServiceDeligate для netServiceDidResolveAddress:, вы можете запустить следующий код для преобразования sockaddr в читаемый IP-адрес:

#include <arpa/inet.h>

-(void)netServiceDidResolveAddress:(NSNetService *)sender {
for (NSData* data in [sender addresses]) {

    char addressBuffer[100];

    struct sockaddr_in* socketAddress = (struct sockaddr_in*) [data bytes];

    int sockFamily = socketAddress->sin_family;

    if (sockFamily == AF_INET ) {//|| sockFamily == AF_INET6) { /*only support ipv4 atm*/

        const char* addressStr = inet_ntop(sockFamily,
                                           &(socketAddress->sin_addr), addressBuffer,
                                           sizeof(addressBuffer));

        int port = ntohs(socketAddress->sin_port);

        if (addressStr && port) {
            //you now have the services IP and Port.. all done
        }
    }
}
[sender release];}

Надеюсь, это поможет любому, кто застрял в этом ... Обратите внимание, что я позаимствовал части других примеров / инструкций в один полный пост, который объясняет всю систему.

Наслаждаться.

person liamnichols    schedule 21.07.2011