У меня странная проблема при отправке UDP-пакетов с iPhone через 3G. Практически каждый раз, когда мое приложение запускается после более длительного периода бездействия сети (например, после того, как телефон выходит из спящего режима или просто получает соединение 3G), мое приложение не может отправлять какие-либо пакеты UDP. Я получаю kCFSocketError
статус ошибки от CFSocketSendData
. Затем логика приложения повторяет попытку периодически отправлять пакет каждые пять секунд, но независимо от того, как долго я позволяю ему запускаться , он продолжает отказывать . Однако, когда я переключаю приложение в фоновый режим и открываю, например, веб-страницу в Safari (в то время как приложение все еще не работает в фоновом режиме), приложение внезапно начинает работать. По сути, похоже, что другие сетевые действия (из Safari, Maps и т. Д.) «Запускают сеть по-настоящему». Нужно ли делать что-то особенное, например, с точки зрения инициализации сети?
Это упрощенный фрагмент кода, который я использую для отправки пакетов UDP:
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
}
Всё работает без проблем по Wi-Fi.
Честно говоря, я думаю, что иногда (но очень редко) я видел такое же поведение в стандартных приложениях для iPhone (Safari, Карты, ...). Иногда они отказываются подключаться (даже думал, что вижу значок 3G), и мне нужно закрыть и снова открыть их. Но это очень редко.
Редактировать: Возможный связанный вопрос: Что на iPhone значит EPERM (errno == 1) в ответ на send () данных UDP? .