2015-09-02 6 views
0

В iOS, когда у меня есть блокирующий сокет с таймаутом, установленным с помощью SO_RCVTIMEO. Когда я меняю сеть Wi-Fi, к которой подключено устройство, вызовы recv будут таймаутом соответственно, но errno будет сообщаться как EWOULDBLOCK, а recv возвращает -1.В iOS, почему сбой recv не сработает при изменении базовой сети?

Это приводит к тому, что мой внешний цикл обработки пытается снова получить доступ к сокету (поскольку, как представляется, сейчас нет данных, когда это реально невозможно в данный момент, поскольку устройство теперь подключено к другой конечной точке сети.

Если я просто полностью уничтожу сеть, несколько повторных вызовов в recv в конечном итоге потерпят неудачу с ETIMEDOUT после многих EWOULDBLOCK.

Почему это происходит? Не следует ли сломать соединение разъема и сбой с помощью ENETRESET или аналогичного errno?

Если у меня нет SO_RCVTIMEO, тогда сокет будет блокироваться навсегда при изменении сети WiFi. Также нет буено.

EDIT: Я бы подумал, что могу включить SO_KEEPALIVE в локальном сокете, чтобы определить, когда удаленный сокет перестает отвечать из-за изменения базовой конечной точки сети. Это тоже не работает.

+0

Изменение на уровне 2 не обязательно означает, что ваши соединения слой 3, являются недействительными. TCP попытается восстановить сокет в течение некоторого времени, прежде чем он в конечном итоге истечет. – Paulw11

+0

Должен ли я быть в состоянии настроить сокет, чтобы нормально работать в этом состоянии? –

ответ

0

Я отправлю свой ответ здесь. Оказывается, при использовании keepalive он должен быть сначала включен для уровня сокета SOL_SOCKET, а также установить интервал keepalive на уровне TCP (уровень IPPROTO_TCP с помощью TCP_KEEPALIVE), поскольку по умолчанию обычно 7200 секунд (2 часа).

int on = 1; 
int delay = 120; 
setsockopt(socket_handle, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)); 
setsockopt(socket_handle, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)); 

Я столкнулся с синтаксисом в соответствии с аналогичным постом.

Is it possible to activate TCP keepalive on Apple iOS devices