2015-09-02 20 views
0

在iOS中,當我使用SO_RCVTIMEO設置超時設置的阻塞套接字時。當我更改設備所連接的WiFi網絡時,對recv的調用將適當超時,但errno將報告爲EWOULDBLOCK,並且recv返回-1。在iOS中,爲什麼套接字recv在底層網絡更改時失敗?

這會導致我的外部處理循環嘗試再次訪問套接字(因爲看起來現在沒有可用的數據),但現實中這是不可能的,因爲此時設備已連接到不同的網絡端點。

如果我完全殺死網絡,幾次重複調用recv最終都會失敗,ETIMEDOUT會在很多EWOULDBLOCK之後失敗。

爲什麼會發生這種情況?套接字連接是否應該被破壞,並且ENETRESET或類似的errno失敗?

如果我沒有SO_RCVTIMEO,那麼當WiFi網絡發生變化時,套接字將永遠阻塞。也沒有bueno。

編輯:我想我可以在本地套接字上啓用SO_KEEPALIVE來檢測遠程套接字由於底層網絡端點更改而停止響應的時間。這似乎也不起作用。

+0

第2層的更改並不一定意味着您的第3層連接無效。 TCP會在最終超時之前嘗試重新建立套接字一段時間。 – Paulw11

+0

在這種情況下,我應該不能配置套接字以正確地失敗嗎? –

回答

0

我會在這裏發表我自己的回答。事實證明,在使用keepalive時,首先必須爲套接字級別SOL_SOCKET啓用它,並且還要在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

相關問題