2

I'm developing an application where devices can connect and interact with each other via common wi-fi network and for the purpose of file exchange I'm using GCDWebServer.

Everything is working great when I use usual wi-fi network or devices are connected to hotspot network with 3rd party host. But I encounter a strange issue when one of devices with the launched app is actually a host of a Hotspot.

I have this code:

- (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);
        }
    });
}

The problem is that serverURL is nil. Which actually seems logical because I checked a function GCDWebServerGetPrimaryIPAddress which is supposed to tell the address and this function is only looking for addresses in the en0 interface when Hotspot network is actually bridge100.

So question is - Is there a "normal" way to make GCDWebServer work with bridge100?

SECOND PART:

Although serverURL is nil, method startWithPort returns true. So I thought maybe server is running, it just can not tell me its address. So I got device's address with my custom method (if you're interested, I can attach it here, but I'm 100% sure it gives a correct address) and tried to use it in order to "speak" with web server, but no luck with that - server doesn't respond. So maybe startWithPort returns a false result after all.

Very interesting observation - when I change primaryInterface to bridge100 in GCDWebServerGetPrimaryIPAddress method, it fixes the issue. GCDWebServer shows a correct address and it is definitely running since I can have an access to the device folder.

Any help would be appreciated!

Eugene Alexeev
  • 1,152
  • 12
  • 32

2 Answers2

2

So question is - Is there a "normal" way to make GCDWebServer work with bridge100?

No. You would need to fork GCDWebServer and patch this function.

Although serverURL is nil, method startWithPort returns true.

The server is certainly running if this method returns true. The ports are open and listening (and by default are bound to all interfaces). The problem is that you need to figure out what IP to use to reach the server from outside the iPhone.

Pol
  • 3,848
  • 1
  • 38
  • 55
  • Hello and thank you for your response! And indeed you are right, server is running! I didn't succeed connecting to it before because I forgot to add 'http:/" prefix to the address. Once I added it, server started to respond to me. I think that was an issue. – Eugene Alexeev Jun 06 '19 at 07:22
0

In order to summarize:

GCDWebServer can be used in the hotspot network although serverURL is nil.

What you need to do is next:

Define IP address of your device on your own. Here's a method you can use:

    - (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) Remember the port you used in order to start GCDWebServer

3) Build your serverURL:

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