2012-12-26 184 views
0

我寫的音頻流光(客戶端 - 服務器)礦山(C/C++)的項目, 和我決定線程UDP服務器這一個多項目。問題實現多線程UDP服務器(線程池?)

這背後的邏輯是,每個客戶端將在自己的線程來處理。 我遇到的問題是線程互相干擾。

我的服務器做的第一件事是創建一種線程池;它創建5個 線程,所有由recvfrom()功能自動封鎖, 雖然看似是,在大多數時候我另一臺設備 連接到服務器,多個線程響應,後來 導致服務器時代完全阻止,不能進一步操作。

這是非常困難的,所以我在這裏寫爲了 獲得多線程UDP服務器是如何實現的,通常一些建議來調試這一點。

我應該使用一個互斥體或信號代碼的一部分嗎?如果是這樣,在哪裏?

任何想法都會非常有幫助。

回答

0

你recvfrom的,應在主線程和當它得到的數據,你應該通過地址IP:端口和UDP客戶端的數據傳輸到輔助線程。

薪火IP:端口和數據可以通過生成一個新的線程,每次主線程來完成接收UDP數據包,也可以通過消息隊列傳遞到輔助線程

+0

感謝您的評論康萊德! 但如果recvfrom函數將在主線程獨自一人,怎麼可能當我們說我的服務器上獲取數據 - 4個客戶機發送出去一次,就它沒有任何問題? –

+0

每個UDP客戶端都被分配一個助手線程。基於UDP IP和客戶端端口的客戶端映射將由主線程維護。在接收數據時,將使用IP和端口將數據轉發到正確的線程。 –

+0

recvfrom函數只接收來自客戶端的UDP數據。它維護一個線程ID表以及每個線程負責的相應客戶端源IP和端口的映射。如果收到一個新數據包並且表中沒有條目,則可以創建一個新線程並在該表中分配一個新條目,並將數據連同客戶端IP和端口一起傳遞給該線程以發送回覆。如果收到新的數據包並且表中已經有映射,則數據通過消息隊列傳遞給該線程。 –

0

我認爲你的主要問題是非持久udp連接。 Udp不會保持連接的活躍,每個會話只交換兩個數據報。根據您的應用程序,在最壞的情況下,它將從第一個可用信息中讀取併發線程,即即使輪到它,recvfrom()也會解除阻塞。

我想,走在主線程中使用選擇,具有並行緩衝,管理什麼至極線程會做的方式。 在此解決方案中,假設您保留客戶端必需的信息以確保發送正確的文件部分,則每個客戶端可以有一個線程或每個文件有一個線程。

TCP是另一種方式來做到這一點,因爲它讓你運行的每個線程活着的連接,而不是在失去了允許的應用程序數據的最佳傳播途徑。

1

我的伺服器第一件事呃確實是創建了一種線程池;它創建了5個線程,所有線程都被recvfrom()函數自動阻塞,但似乎在大多數情況下,當我將另一個設備連接到服務器時,多個線程都會響應,並且稍後會導致服務器成爲完全堵塞和不超過其所有的線程坐在一個recvfrom的()同一個套接字連接上進一步操作

相反,你應該保護與信號的連接,讓您的工作線程等待信號量。當一個線程獲得信號量時,它可以調用recvfrom(),當它返回一個數據包時,線程可以釋放信號量(用於獲取另一個線程)並處理數據包本身。當它完成數據包的服務後,它可以返回等待信號量。這樣可以避免在線程之間傳輸數據。