Linux下伺服器遭遇SIGPIPE訊號

2021-06-21 14:05:35 字數 1240 閱讀 4166

sigpipe訊號產生原因:

我查了一下, 對乙個對端已經關閉的socket呼叫兩次write, 第二次將會生成sigpipe訊號, 該訊號預設結束程序.

我寫了乙個伺服器程式,在linux下測試,伺服器總是莫名退出,剛開始以為是段錯誤,但是怎麼弄都沒有core檔案。

最後問題確定為, sigpipe訊號結束了程序。我的伺服器主動關閉了socket,然後又對該socket write了兩次,系統產生了sigpipe訊號,結束了程序。

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

這個訊號的預設處理方法是退出程序,大多數時候這都不是我們期望的。因此我們需要更改這個訊號的處理方法。

呼叫以下**,即可安全的遮蔽sigpipe:

signal (sigpipe, sig_ign);

具體的分析可以結合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. 程式便能知道對端已經關閉.

對於產生的訊號,我們可以在產生訊號前利用方法 signal(int signum, sighandler_t handler) 設定訊號的處理。

如果沒有呼叫此方法,系統就會呼叫預設處理方法:中止程式,顯示提示資訊(就是我們經常遇到的問題)。

我們可以呼叫系統的處理方法,也可以自定義處理方法相應訊號。

Linux下CVS伺服器

2.在 etc xinetd.d下面建立乙個檔案cvspserver,其內容如下 service cvspserver 其中cvs命令在 usr bin目錄下,而設定cvs工作根目錄是 cvs。3.重新啟動xinetd超級伺服器,使用下面命令 etc init.d xinetd restart 4....

linux 下CA伺服器安裝

來自 http hi.baidu.com mx87 blog item 32ca90fc715ffcfffd037f08.html 3 解壓 命令 tar xzvf openssl 0.9.7e.tar.gz 4 進入openssl目錄,並安裝,用 prefix指定openssl安裝目錄 命令 cd...

Linux下配置DHCP伺服器

redhat使用dhcpd程序提供dhcp服務,啟動時dhcpd自動讀它的配置檔案 etc dhcpd.conf。dhcpd將客戶的租用資訊儲存在 var lib dhcp dhcpd.leases檔案中,該檔案不斷被更新,從這裡面可以查到ip位址分配的情況。dhcpd為了向乙個子網提供服務,需要知...