2011-03-04 188 views
3

我正在設計和測試基於TCP套接字(Internet域)的客戶端服務器程序。目前,我正在我的本地機器上測試它,但無法理解關於SIGPIPE的以下內容。TCP客戶端服務器SIGPIPE

*。 SIGPIPE顯得非常隨機。它可以是確定性的嗎?

第一次測試包括從客戶端發送單個小(25個字符)的發送操作和在服務器上的相應接收。相同的代碼,在同一臺機器上運行成功與否(SIGPIPE)完全不受我的控制。失敗率約爲45%(相當高)。那麼,我能否以任何方式調整機器以最大限度地減少這種情況。

**。第二輪測試是從客戶端向服務器發送40000條(25個字符)的消息(總數據爲1MB),然後服務器響應它實際收到的數據的總大小。客戶端以嚴格的循環方式發送數據,並且在服務器上有一個單一的接收呼叫。它僅適用於發送總數據的最大1200字節,而且還有非確定性SIGPIPE,現在大約70%(非常糟糕)。

有人可以在我的設計中提出一些改進(可能它會在服務器上)。要求客戶端應能夠在向服務器發送單個套接字連接之後發送中等到非常高的數據量(每個消息約25個字符)。 我有一種感覺,多次發送反對單一接收將始終是有損和非常低效。我們是否可以合併消息並只發送一個send()操作。這是唯一的方法嗎?

回答

7

當您嘗試寫入未連接的管道/套接字時發送SIGPIPE。爲信號安裝一個處理程序將使send()返回一個錯誤。

signal(SIGPIPE, SIG_IGN); 

或者,您可以禁用插槽SIGPIPE:

int n = 1; 
setsockopt(thesocket, SOL_SOCKET, SO_NOSIGPIPE, &n, sizeof(n)); 

此外,數據量你提都不會很高。可能有某處導致連接意外關閉的錯誤,並提供SIGPIPE。

+1

請注意,SO_NOSIGPIPE不可移植。看到這裏:http://stackoverflow.com/questions/108183/how-to-prevent-sigpipes-or-handle-them-properly – 2013-06-18 17:26:19

1

SIGPIPE因爲您試圖寫入已關閉的套接字而引發。這確實表明一個可能的錯誤,所以請檢查你的應用程序,以瞭解它爲什麼會發生,並嘗試首先修復它。

試圖只屏蔽SIGPIPE並不是一個好主意,因爲您不知道信號來自哪裏,您可能會屏蔽其他來源的錯誤。在多線程環境中,信號是一個可怕的解決方案。

在極少數情況下,您無法避免這種情況,您可以屏蔽發送信號。如果您將MSG_NOSIGNAL標誌設置爲send()/sendto(),則會阻止引發SIGPIPE。如果確實觸發此錯誤,則send()返回-1,errno將設置爲EPIPE。清潔和簡單。詳情請參閱man send