即使遠程端關閉了連接,send()系統調用也會第一次成功。 如果我再次發送,那麼將生成sigpipe。 我不想使用recv系統調用來知道遠端是否關閉了連接。如何知道遠端是否使用send系統調用關閉了socket?
那麼有人可以告訴我如何檢測遠端是否僅使用發送系統調用關閉連接?
即使遠程端關閉了連接,send()系統調用也會第一次成功。 如果我再次發送,那麼將生成sigpipe。 我不想使用recv系統調用來知道遠端是否關閉了連接。如何知道遠端是否使用send系統調用關閉了socket?
那麼有人可以告訴我如何檢測遠端是否僅使用發送系統調用關閉連接?
你應該做的第一件事就是打電話signal(SIGPIPE, SIG_IGN);
避免收到關於send()
SIGPIPE
,或者在Linux上,通過MSG_NOSIGNAL
標誌send()
。這樣做後,send()
將不會生成SIGPIPE
信號,當對等體已斷開連接時,而是返回-1與errno == EPIPE
。
發送SIGPIPE
是write()
函數的歷史行爲。 http://pubs.opengroup.org/onlinepubs/009604599/functions/write.html
EPIPE
試圖寫入到未通過任何方法開用於讀取,或僅具有一個一端開口的管或FIFO
。一個SIGPIPE
信號也將被髮送到該線程。
最初它是爲殼管(如cmd | other_cmd
)創建的。當在外殼管道執行期間按下ctrl-c
時,只有管道中的最後一個進程接收到SIGINT
並終止。要終止管道中的其他進程SIGPIPE
將發送到試圖將write()
轉換爲STDOUT
的進程,該進程的閱讀器已終止。
這是因爲,send()會搶佔內核去處理軟件中斷(隨後調用信號處理程序);在這種情況下,一些系統可能試圖重新啓動搶佔系統調用的執行,即send()?基本上該程序可以循環? –
更新了答案。 –