Linux SIGPIPE訊號產生原因與解決方法

2022-06-18 11:06:08 字數 1629 閱讀 7420

sigpipe訊號產生的原因:

當伺服器close乙個連線時,若client端接著發資料。根據tcp協議的規定,會收到乙個rst響應,client再往這個伺服器傳送資料時,系統會發出乙個sigpipe訊號給程序,告訴程序這個連線已經斷開了,不要再寫了。

又或者當乙個程序向某個已經收到rst的socket執行寫操作時,核心向該程序傳送乙個sigpipe訊號。該訊號的預設操作是終止程序,因此程序必須

捕獲它以免不情願的被終止

tcp的全雙工通道其實是兩條單工通道,client端呼叫close的時候,雖然本意是關閉兩條通道,但是其實只能關閉它傳送的那一條單工通道,還是可以接受資料,server端還是可以傳送資料,並不知道client端已經完全關閉了。

以下為引用:

」』對乙個已經收到fin包的socket呼叫read方法, 如果接收緩衝已空, 則返回0, 這就是常說的表示連線關閉. 但第一次對其呼叫write方法時, 如果傳送緩衝沒問題, 會返回正確寫入(傳送). 但傳送的報文會導致對端傳送rst報文, 因為對端的socket已經呼叫了close, 完全關閉, 既不傳送, 也不接收資料. 所以, 第二次呼叫write方法(假設在收到rst之後), 會生成sigpipe訊號,導致程序退出.」』

linux 系統為大部分訊號定義了預設處理方法,當訊號的預設處理方法不滿足需求時,可通過 sigaction()函式進行改變。

如:signal(sigpipe, sig_ign);

這時sigpipe交給了系統處理。

伺服器採用了fork的話,要收集垃圾程序,防止殭屍程序的產生,可以這樣處理:

signal(sigchld,sig_ign);
交給系統init去**。

這裡子程序就不會產生殭屍程序了。

在linux下寫socket的程式的時候,如果嘗試send到乙個disconnectedsocket上,就會讓底層丟擲乙個sigpipe訊號。

這個訊號的預設處理方法是退出程序,大多數時候這都不是我們期望的。因此我們需要過載這個訊號的處理方法。呼叫以下**,即可安全的遮蔽sigpipe:

struct

sigaction sa;

sa.sa_handler =sig_ign;

sigaction( sigpipe, &sa, 0 );

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)

linux SIGPIPE訊號處理

在linux下寫socket的程式的時候,如果嘗試send到乙個disconnected socket上,就會讓底層丟擲乙個sigpipe訊號。這個訊號的預設處理方法是退出程序,大多數時候這都不是我們期望的。因此我們需要過載這個訊號的處理方法。呼叫以下 即可安全的遮蔽sigpipe struct s...

製造企業需要APS生產計畫排產的五大訊號

製造企業中的一些生產經理經常認為,他們的工廠還沒有做好準備實施aps生產計畫排產軟體。雖然為整個企業實現乙個新的軟體,確實是乙個重大的決定,但在出現重大生產問題之前,考慮實施乙個軟體是很有必要的。aps生產計畫排產軟體一旦出現問題,員工就會非常緊張,爭先恐後地輸入資料,學習新的系統,並改進以及提高工...

母牛產牛問題

一頭母牛從出生後,每兩年可以生下一頭母牛,即在第二年和第四年分別可產下一頭母牛,出生後第五年將會死去。假設農場現有一頭母牛,n年後農場的母牛數目是多少,編寫程式實現 用五個數字或陣列來記錄當前歲數的牛的個數,每增長一年的時候都會年長一歲的個數變為上次小一歲的個數,即x4 x3 x3 x2 x2 x1...