2009-08-25 26 views
8

如果連接了一個tcp服務器和客戶端,我想確定客戶端何時不再連接。我想我可以簡單地通過嘗試向客戶端發送消息來做到這一點,一旦send()返回-1,我就可以拆卸套接字。這個實現可以在Windows上找到,但是當我嘗試在BSD套接字的Linux上執行此操作時,服務器端應用程序對send()的調用會導致我的服務器應用程序在客戶端不再連接時崩潰。它甚至不返回-1,只是終止程序。TCP發送不會導致崩潰進程

請解釋爲什麼會發生這種情況。提前致謝!

回答

13

這是由SIGPIPE信號引起的。見send(2):如果

的發送()函數將失敗:
[EPIPE] 插座關閉寫入,或者套接字連接模式和不再連接。在後一種情況下,如果套接字的類型爲SOCK_STREAM或SOCK_SEQPACKET且MSG_NOSIGNAL標誌未設置,則會向調用線程生成SIGPIPE信號。

您可以通過使用在send()呼叫MSG_NOSIGNAL標誌,或在你的程序的開始忽略SIGPIPE信號與signal(SIGPIPE, SIG_IGN)避免這種情況。然後在這種情況下,send()函數將返回-1並將errno設置爲EPIPE

2

您需要忽略SIGPIPE信號。如果在套接字上發生寫入錯誤,使用SIGPIPE進行處理,並且該信號的默認行爲是終止進程。 在* nix上編寫網絡代碼您通常需要:

signal(SIGPIPE,SIG_IGN);