如何解決ios SIGPIPE 導致的崩潰
阿新 • • 發佈:2019-02-04
在開發ios長連線遊戲的過程中遇到一個問題:在遊戲執行過程中玩家按下home鍵或者其他原因遊戲被掛起,socket連線不會斷開,伺服器為了節省資源,在一段時間後會主動關閉這個連線。當玩家再次切回到遊戲後,前端並不知道這個連線已經斷開了,繼續通過斷開的socket傳送訊息,這時候send函式會觸發SIGPIPE異常導致程式崩潰。
解決這個問題我們需要在send的時候檢測到伺服器已經關閉連線,進行重新連線。正常情況下send函式返回-1表示傳送失敗,但是在IOS上SIGPIPE在send返回之前就終止了程序,所以我們需要忽略SIGPIPE,讓send正常返回-1,然後重新連線伺服器。
查閱資料後找到了兩個方法:
1) 使用 signal(SIGPIPE, SIG_IGN) 忽略SIGPIPE。經實驗在ios7模擬器上雖然xcode還是會捕獲SIGPIPE,但是程式不會崩潰,繼續後可以執行。但是在真機上依然會崩潰。
2) 使用 SO_NOSIGPIPE。 經實驗在多個ios版本下都不再觸發SIGPIPE,完美解決問題。
int set = 1;
setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int));