每日一貼,今天的內容關鍵字為訊號方法
每日一道理
誰說人與人隔著遙遠的重洋,誰說心與心設著堅固的堤防?十六歲的鳥兒飛上天空,總會找到落腳的枝頭。
我寫了乙個伺服器程式,在linux下測試,然後用c++寫了客戶端用千萬級別數量的短鏈結進行壓力測試. 但是伺服器總是莫名退出,沒有core檔案.
最後問題確定為, 對乙個對端已關閉的socket呼叫兩次write, 第二次將會生成sigpipe訊號, 該訊號預設結束程序.
詳細的分析可以結合tcp的"四次握手"關閉. tcp是全雙工的通道, 可以看做兩條單工通道, tcp連線兩頭的兩個端點各負責一條. 當對端呼叫close時, 雖然本意是關閉全部兩條通道, 但本端只是收到fin包. 按照tcp協議的語義, 表現對端只是關閉了其所負責的那一條單工通道, 仍然可以繼承接收資料. 也就是說, 因為tcp協議的限制, 乙個端點無法獲知對端的socket是呼叫了close還是shutdown.
對乙個已收到fin包的socket呼叫read方法, 如果接收緩衝已空, 則返回0, 這就是常說的表現連線關閉. 但第一次對其呼叫write方法時, 如果傳送緩衝沒問題, 會返回正確寫入(傳送). 但傳送的報文會導致對端傳送rst報文, 因為對端的socket已呼叫了close, 完整關閉, 既不傳送, 也不接收資料. 所以, 第二次呼叫write方法(假設在收到rst以後), 會生成sigpipe訊號, 導致程序退出.
為了防止程序退出, 可以捕獲sigpipe訊號, 或者忽略它, 給它設定sig_ign訊號處置函式:
signal(sigpipe, sig_ign);
這樣, 第二次呼叫write方法時, 會返回-1, 同時errno置為sigpipe. 程式便能曉得對端已關閉.
在linux下寫socket的程式的時候,如果嘗試send到乙個disconnected socket上,就會讓底層丟擲乙個sigpipe訊號。
這個訊號的預設處置方法是退出程序,大多數時候這都不是我們期望的。因此我們需要過載這個訊號的處置方法。呼叫以下**,便可安全的遮蔽sigpipe:
signal (sigpipe, sig_ign);
我的程式發生這個訊號的原因是:
client端通過 pipe 傳送資訊到server端後,就關閉client端, 這時server端,返回資訊給 client 端時就發生broken pipe 訊號了,伺服器就會被系統結束了。
對於發生訊號,我們可以在發生訊號前利用方法 signal(int signum, sighandler_t handler) 設定訊號的處置。如果沒有呼叫此方法,系統就會呼叫預設處置方法:中斷程式,顯示提示資訊(就是我們經常遇到的問題)。我們可以呼叫系統的處置方法,也可以自定義處置方法。
系統裡邊定義了三種處置方法:
(1)sig_dfl訊號專用的預設動作:
(a)如果預設動作是暫停執行緒,則該執行緒的執行被暫時掛起。當執行緒暫停期間,傳送給執行緒的任何附加訊號都不交付,直到該執行緒開始執行,但是sigkill除外。
(b)把掛起訊號的訊號動作設定成sig_dfl,且其預設動作是忽略訊號 (sigchld)。
(2)sig_ign忽略訊號
(a)該訊號的交付對執行緒沒有影響
(b)系統不允許把sigkill或sigtop訊號的動作設定為sig_dfl
3)sig_err
專案中我呼叫了signal(sigpipe, sig_ign), 這樣發生 sigpipe 訊號時就不會中斷程式,直接把這個訊號忽略掉。
文章結束給大家分享下程式設計師的一些笑話語錄: bphone之你們聊,我先走了!移動說:我在phone前加o,我叫o縫;蘋果說:我在phone前i,我是i縫;微軟說:我在phone前加w,我叫w縫;三星說:你們聊,我先走了!
將來王建宙寫回憶錄的時候,一定要有一句「常小兵為中國移動的發展做出了不可磨滅的貢獻」。
關於SIGPIPE訊號
我寫了乙個伺服器程式,在linux下測試,然後用c 寫了客戶端用千萬級別數量的短鏈結進行壓力測試.但是伺服器總是莫名退出,沒有core檔案.最後問題確定為,對乙個對端已經關閉的socket呼叫兩次write,第二次將會生成sigpipe訊號,該訊號預設結束程序.具體的分析可以結合tcp的 四次握手 ...
關於SIGPIPE訊號
我寫了乙個伺服器程式,在linux下測試,然後用c 寫了客戶端用千萬級別數量的短鏈結進行壓力測試.但是伺服器總是莫名退出,沒有core檔案.最後問題確定為,對乙個對端已經關閉的socket呼叫兩次write,第二次將會生成sigpipe訊號,該訊號預設結束程序.具體的分析可以結合tcp的 四次揮手 ...
關於SIGPIPE訊號
我寫了乙個伺服器程式,在linux下測試,然後用c 寫了客戶端用千萬級別數量的短鏈結進行壓力測試.但是伺服器總是莫名退出,沒有core檔案.最後問題確定為,對乙個對端已經關閉的socket呼叫兩次write,第二次將會生成sigpipe訊號,該訊號預設結束程序.具體的分析可以結合tcp的 四次握手 ...