2010-04-07 68 views
-1

下面的代碼塊時並行至4-5線程運行良好,但作爲啓動的線程的數目某處增加超過10個併發線程Socket.Recieve失敗當多線程

int totalRecieved = 0; 
int recieved; 
StringBuilder contentSB = new StringBuilder(4000); 
while ((recieved = socket.Receive(buffer, SocketFlags.None)) > 0) 
{ 
    contentSB.Append(Encoding.ASCII.GetString(buffer, 0, recieved)); 
    totalRecieved += recieved; 
} 

Recieve方法返回失敗零字節被讀取,如果我繼續調用接收方法,那麼我最終會得到異常'已建立的連接被主機中的軟件中止'。所以我假設主機實際上發送了數據然後關閉了連接,但由於某種原因,我從未收到過它。

我很好奇爲什麼當有很多線程出現這個問題。我認爲它必須與這樣一個事實有關,即每個線程的執行時間不會太多,因此導致此錯誤的線程有一些空閒時間。只是不知道爲什麼空閒時間會導致套接字不能接收任何數據。

編輯:只是爲了澄清。每個線程都有自己的個人套接字讀取不同的數據。

+0

要明確一點,每個線程都有自己的套接字? – 2010-04-07 20:14:47

+0

我不清楚的是,如果你有很多線程每個線程讀一個套接字或一個套接字? – ParmesanCodice 2010-04-07 20:15:24

+0

你知道SocketError代碼(SocketException.ErrorCode)嗎?可能是一個超時... – ParmesanCodice 2010-04-07 20:30:16

回答

0

問題是嘗試在多個線程的同一個套接字上使用Receive。

Socket class的MSDN文檔特別建議在執行期間,一個套接字的Receive方法只能由單個線程和一個線程使用。

對於需要使用多個線程從同一套接字讀取數據時,就應該把應用程序:

  • 使用BeginReceiveEndReceive的建議,MSDN,或者

  • 使用一個單一的插座讀線程接收數據包,然後將每個數據包寫入同步隊列。您可能會有多個線程將數據從隊列中提取出來。

+0

好點。猜猜我會改變爲異步方法。仍然不明白爲什麼同步方法會失敗。 – 2010-04-07 20:26:23

+0

MSDN特別聲明,您不應該使用「接收」處理與多個線程的通信。由於線程的執行是非確定性的,它們的實現可能恰好(或似乎)以少於4個線程正常工作。 – 2010-04-07 20:47:07

+3

MSDN的寫法有點令人困惑,當你有多個線程時使用'Receive'並不是問題。這個問題試圖在多個線程的同一套接字上使用'Receive'。如果每個線程正在處理不同的套接字,那麼在兩個不同的線程上使用它就沒有問題。 – 2010-04-08 05:25:50

1

打開的連接有系統限制,請參閱啓動器this SO question。這裏有一些more info

+0

由於@ Qua未顯示Socket對象是如何構造的,因此可能會觸及此限制。 – 2010-04-08 02:35:26

+1

我增加了一個新的答案,因爲接受的答案是錯誤的。許可限制爲10只適用於由MS提供的應用程序協議。還有其他一些原因也是10 ...您的其他鏈接更好,因爲它提供了其中一些鏈接(例如,不超過10個半開放TCP連接,在1秒內不超過10個新連接)。 – 2010-04-08 05:28:33

+0

@Kevin:我知道有關於此的更好的Q + A,但我找不到它們) - : – 2010-04-08 08:32:54