Linux下socket編程write()函數崩潰導致進程退出

問題描述:

當服務器close一個連接時,若client端接着發數據。根據TCP協議的規定,會收到一個RST響應,client再往這個服務器發送數據時,系統會發出一個SIGPIPE信號給進程,告訴進程這個連接已經斷開了,不要再寫了。

又或者當一個進程向某個已經收到RSTsocket執行寫操作是,內核向該進程發送一個SIGPIPE信號。該信號的缺省學位是終止進程,因此進程必須捕獲它以免不情願的被終止。

我遇到的情況是客戶端socket句柄已關閉,然後服務器像一個已關閉的客戶端連接句柄中執行寫操作,從而產生了SIGPIPE信號。

問題原因:

根據信號的默認處理規則SIGPIPE信號的默認執行動作是terminate(終止、退出),所以進程會退出。

系統裏邊定義了三種處理方法: 
    1)SIG_DFL     
    2)SIG_IGN     
    3)SIG_ERR     

根據信號的默認處理規則SIGPIPE信號的默認執行動作是terminate(終止、退出),所以進程會退出。若不想客戶端退出,需要把 SIGPIPE默認執行動作屏蔽

問題解決:

將SIGPIPE的默認處理方法屏蔽,我找到了兩種方法:用signal(SIGCHLD,SIG_IGN)或者重載其處理方法。個人選了後者。兩者區別在於signal設置的信號句柄只能起一次作用,信號被捕獲一次後,信號句柄就會被還原成默認值了;sigaction設置的信號句柄,可以一直有效,值到你再次改變它的設置。具體代碼如下:

struct sigaction action;

action.sa_handler = handle_pipe;

sigemptyset(&action.sa_mask);

action.sa_flags = 0;

sigaction(SIGPIPE, &action, NULL);

void handle_pipe(int sig)

{//不做任何處理即可}

在源文件中要添加signal.h頭文件:#include <signal.h>。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章