signal(SIGPIPE, SIG_IGN)
signal(SIGPIPE, SIG_IGN)
最後問題確定為, 對一個對端已經關閉的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 訊號時就不會中止程式,直接把這個訊號忽略掉。
相關文章
- Linux Signal 示例Linux
- signal協議協議
- golang處理signalGolang
- python 之訊號SignalPython
- unix signal : signalfd, eventfd, timerfd
- Recursive Algorithm for Sliding Signal ProcessingGo
- os/signal學習筆記筆記
- Linux訊號(signal)機制Linux
- wifi管理神器:WiFi Signal MacWiFiMac
- Linux alarm signal (SIGALRM) to detach process isAliveLinux
- AQS相關(lock、unlock、await、signal)AQSAI
- Signal:更多前端框架的選擇前端框架
- MetricMeasurement calculates Peak Signal-to-Noise RatioREM
- Message from debugger: Terminated due to signal 13
- 每週一個 Python 模組 | signalPython
- iOS Mach異常和signal訊號iOSMac
- 公司不是家庭 -DHH from Signal v.Noise
- 論文解讀《The Emerging Field of Signal Processing on Graphs》
- WiFi訊號監測工具:WiFi Signal for MacWiFiMac
- Signal Desktop for Mac專業加密通訊工具Mac加密
- 數字成像系統ISP(Image signal processor)原理
- SciTech-BigDataAIML-CV+CG-Digital Image/Signal Processing-AIGit
- WebThread:signal SIGABRT 和 libc++abi.dylib:terminating with uncaughtWebthreadC++
- Linux安裝即時通訊軟體SignalLinux
- 詳解Condition的await和signal等待/通知機制AI
- qt傳送自定義signal,直接呼叫也可以,不使用emitQTMIT
- Open Signal:2022年全球行動網路體驗獎報告
- 系統程式設計-訊號-總體概述和signal基本使用程式設計
- 開源相機管理庫Aravis例程學習(四)——multiple-acquisition-signalUI
- xenomai核心解析之訊號signal(二)---xenomai訊號處理機制AI
- Java併發程式設計,Condition的await和signal等待通知機制Java程式設計AI
- 論文翻譯:2020_ACOUSTIC ECHO CANCELLATION WITH THE DUAL-SIGNAL TRANSFORMATION LSTM NETWORKORM
- I/O複用3個小例項+將signal轉化為IO事件事件
- 論文翻譯六:A novel underwater acoustic signal denoising algorithm for Gaussian/non-Gaussian impulsiveGo
- Signal如何使用Rust構建大規模端到端加密視訊通話?Rust加密
- Django 使用心得 (三)利用 middleware 和 signal 實現資料的 「create_by」 記錄功能Django
- Java併發包原始碼學習系列:詳解Condition條件佇列、signal和awaitJava原始碼佇列AI
- WiFi訊號強度監測管理軟體 WiFi Signal mac v4.4.10中文版WiFiMac
- 母雞下蛋例項:多執行緒通訊生產者和消費者wait/notify和condition/await/signal條件佇列執行緒AI佇列