views:

201

answers:

0

I'm having a strange problem when sending UDP packets from an iPhone over a 3G. Almost every time my application starts after a longer period of network inactivity (for instance after the phone comes from the sleep mode or it just gets a 3G connection), my application is not able to send any UDP packets. I get a kCFSocketError error status from CFSocketSendData. The application logic then re-tries to send the packet periodically every five seconds, but no matter how long I let it run it keeps failing. However, when I switch the application to background and open, for instance, a web page in Safari (while the application is still failing on background), the application suddenly starts working. Basically, it seems like the other network activity (from Safari, Maps etc.) "kicks off the networking for real". Do I need to do anything special in terms of network initialisation for instance?

This is a simplified snippet of the code I'm using to send the UDP packets:

CFSocketRef cfSocket = CFSocketCreate(NULL, 0, SOCK_DGRAM, IPPROTO_UDP, kCFSocketNoCallBack, NULL, NULL);
if (!cfSocket)
{
    // snip: some error handling
}

struct sockaddr_in addr;
// snip: init addr

CFDataRef cfAddr = CFDataCreate(NULL, (unsigned char *)&addr, sizeof(addr));

CFSocketError sendPacketResult = CFSocketSendData(cfSocket, cfAddr, cfPacketData, 0.0);
if (sendPacketResult != kCFSocketSuccess)
{
    // try again in 5 seconds
}

It all works fine without any problems over Wi-Fi.

To be fair, I think I've seen sometimes (but very occasionally) the same behaviour in the standard iPhone applications (Safari, Maps, ...) as well. Sometimes they refuse to connect (even thought I see the 3G icon) and I need to close and reopen them. But it's very rare.

Edit: Possibly related question: On iPhone, what does EPERM (errno == 1) mean in reponse to send() of UDP data?.