Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getaddrinfo in iPhone

I prepare a small application. When I restart my iPhone 3G (with 3G Internet connection) and install this application, getaddrinfo() always returns EAI_NONAME (8). I close the application and run Safari, then run my application - all works. What's the problem?

- (void)viewDidLoad {
    [super viewDidLoad];

    const char* hostname = "google.com";

    struct addrinfo hints, *res;
    int retval;

    memset (&hints, 0, sizeof (struct addrinfo));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    retval = getaddrinfo (hostname, NULL, &hints, &res);
    if (retval == 0) {
        freeaddrinfo (res);
    }else if(retval == EAI_NONAME)
    {
        //noname
    }
}

Answer from Apple:

Hello Pavel,

I'm responding regarding your finding that trying to use the BSD getaddrinfo function is problematic when trying to get a connection where only a Wireless Wide Area Network (WWAN) connection is possible (EDGE, 3G). The issue you've encountered is that for battery saving reasons, WWAN will shutdown when network services are not needed. The question then becomes, how to activate WWAN, when network services are required.

The officially supported mechanism to establish a WWAN connection is to use the CFSocketStream API (or dependent API - NSSocket, as well as CFHTTPStream, CFFTPStream, NSURLRequest, and NSURLConnection API's). This means that officially, only TCP is supported. This limitation impacts all UDP and BSD Socket based applications. The use of a BSD Connect call will not trigger the iPhone to enable WWAN. This limitation also applies to all other BSD functions which under a WiFi connection would result in a packet transmission.

However, under the current iPhone OS, once a WWAN connection is established, the use of BSD sockets and CFSocket functions, will keep the WWAN connection alive. This makes it possible for a UDP or BSD Socket based application to establish a WWAN connection by using the CFSocketStream API to establish a connection with a TCP server (including HTTP Web Servers). Once the connection is active, then the program can function as it has in the past. This is what Safari, Mail, and other Apple applications which access network services, uses to establish their connections. For this reason, when you launch Safari, then launch your application network access works. Using Safari causes the iPhone to establish a WWAN connection. When you quit Safari, WWAN does not automatically shutdown - it remains active for a short period of time. If you launch your application, WWAN services are active and your application will cause WWAN to remain active so long as there is network activity.

If your application were to use TCP, for networking, then you could modify your code to use the CFSocketStream or dependent API, for networking. Of course, if you have a whole library of BSD socket functionality, this may not be a reasonable solution for someone who wants to get their application onto the App Store real soon.

....

like image 214
Pavel Kurta Avatar asked Nov 14 '22 15:11

Pavel Kurta


1 Answers

What's probably happening here is that getaddrinfo() is not blocking to wait for the DNS lookup, which is possibly a good thing since DNS lookups on iPhone can take a very long time. Once you've done the lookup elsewhere, it's giving you the cached answer.

Take a look at CFHost, which is the preferred way to get this kind of information on iPhone. It supports asynchronous callbacks to let you know when the information is available, or you can make synchronous calls if you like.

like image 116
Rob Napier Avatar answered Dec 14 '22 23:12

Rob Napier