GCDWebServer через сеть Hotspot - PullRequest
1 голос
/ 05 июня 2019

Я разрабатываю приложение, в котором устройства могут подключаться и взаимодействовать друг с другом через общую сеть Wi-Fi, и для обмена файлами я использую GCDWebServer.

Все работает отлично, когдаЯ использую обычную сеть Wi-Fi или устройства подключены к сети точек доступа с хостом стороннего производителя.Но я сталкиваюсь со странной проблемой, когда одно из устройств с запущенным приложением на самом деле является хостом Hotspot.

У меня есть этот код:

- (void)startStreamHLSServer
{
    dispatch_async(dispatch_get_main_queue(), ^{
        if (!_webServer.isRunning)
        {
            _webServer = [GCDWebServer new];
            [_webServer addGETHandlerForBasePath:@"/" directoryPath:[_fileManager videosURL].path indexFilename:nil cacheAge:3600 allowRangeRequests:YES];

            [_webServer startWithPort:1000 bonjourName:nil];

            NSLog(@"URL: %@", _webServer.serverURL.absoluteString);
        }
    });
}

Проблема в том, что serverURL равен nil.Что на самом деле кажется логичным, потому что я проверил функцию GCDWebServerGetPrimaryIPAddress, которая должна сообщать адрес, и эта функция ищет адреса только в интерфейсе en0, когда сеть Hotspot на самом деле bridge100.

Так что вопросis - есть ли "нормальный" способ заставить GCDWebServer работать с bridge100?

ВТОРАЯ ЧАСТЬ:

Хотя serverURL равен нулю, метод startWithPortвозвращает true.Поэтому я подумал, что, возможно, сервер работает, он просто не может сказать мне свой адрес.Таким образом, я получил адрес устройства с помощью своего пользовательского метода (если вам интересно, я могу прикрепить его здесь, но я на 100% уверен, что он дает правильный адрес) и попытался использовать его, чтобы «говорить» с веб-сервером,но не повезло с этим - сервер не отвечает.Поэтому, возможно, startWithPort в конце концов возвращает ложный результат.

Очень интересное наблюдение - когда я изменяю primaryInterface на bridge100 в методе GCDWebServerGetPrimaryIPAddress, это устраняет проблему.GCDWebServer показывает правильный адрес, и он определенно работает, так как я могу иметь доступ к папке устройства.

Любая помощь будет признательна!

Ответы [ 2 ]

1 голос
/ 06 июня 2019

Итак, вопрос в том, существует ли "нормальный" способ заставить GCDWebServer работать с bridge100?

Нет.Вам нужно было бы разветвить GCDWebServer и исправить эту функцию.

Хотя serverURL равен nil, метод startWithPort возвращает true.

Сервер, безусловно, работает, если этот метод возвращает значение true.Порты открыты и прослушиваются (и по умолчанию привязаны ко всем интерфейсам).Проблема в том, что вам нужно выяснить, какой IP-адрес использовать для доступа к серверу вне iPhone.

0 голосов
/ 06 июня 2019

Для суммирования:

GCDWebServer можно использовать в сети точек доступа, хотя serverURL равно нулю.

Что вам нужно сделать, это следующее:

Определите IP-адрес вашего устройства самостоятельно. Вот метод, который вы можете использовать:

    - (void)getDeviceAddress
    {
        NSString *address = @"";
        struct ifaddrs *interfaces = NULL;
        struct ifaddrs *temp_addr = NULL;
        int success = 0;

        // retrieve the current interfaces - returns 0 on success
        success = getifaddrs(&interfaces);

        if (success == 0)
        {
            temp_addr = interfaces;

            while(temp_addr != NULL)
            {
                if(temp_addr->ifa_addr->sa_family == AF_INET)
                {
                    NSString *interfaceName = [NSString stringWithUTF8String:temp_addr->ifa_name];
                    if([interfaceName isEqualToString:@"bridge100"] || [interfaceName isEqualToString:@"en0"])
                    {
                        //fetch ip address
                        address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                        break;
                    }
                }

                temp_addr = temp_addr->ifa_next;
            }
        }

        freeifaddrs(interfaces);
        return address;
}

2) Запомните порт, который вы использовали для запуска GCDWebServer

3) Создайте свой serverURL:

- (NSString *)serverURL {
    NSString *serverURL = [NSString stringWithFormat:@"http:/%@:%d", [self getDeviceAddress], serverPort]; //serverPort is the port your GCDWebServer is running on
    return serverURL;
}
...