在linux下編寫TCP socket程序時,如果客戶端突然退出,導緻連接中斷,這個時候服務端如果繼續調用send函數發送數據的話,會導緻整個進程退出,這是我們不願看到的。(注:如果是服務端突然退出,客戶端繼續調用send發送,是不會導緻進程退出的)。
為什麼會退出進程而不是返回一個錯誤值呢?感覺有點“霸道”,連留給我們處理問題的機會都沒有。
原來,當服務端嘗試使用一個disconnected socket進行send數據時,會讓低層抛出一個SIGPIPE信号,這個信号的缺省處理方法是退出進程!
知道了問題原因後,處理就容易多了,比較簡單的方法有以下2種:
重新定義一個信号處理函數,覆蓋系統默認處理方法void signal_process(){ //process code}signa(SIGPIPE, signa_process);這樣,進程就不會退出了。
修改send函數最後一個參數linux下send函數原型為:
ssize_t send(int fd, const void*buf, size_t n, int flags);其中,flags被忽略了,一般設置為0,但當flags為0時,如果客戶端斷開,服務端繼續send時,會引發一個信号SIGPIPE,此信号會引發進程退出。
所以隻需要把flags設置為MSG_NOSIGNAL,則不會導緻信号退出。MSG_NOSIGNAL的含義是,當對方斷開連接導緻錯誤時,不發送SIGPIPE信号,但還是會返回EPIPE錯誤。
這樣,進程不退出,我們隻需要判斷send的返回值是否小于或等于0,就知道send函數是否調用成功!
,
更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!