2012-07-06 41 views
2

我是C#的新手,主要完成過去基於Web的編碼。我正在創建一個將與單個客戶端通信的TCP服務器。我知道我需要多個線程,因爲我不希望我的程序阻止等待連接(或讀取數據,發送等)。針對單個客戶端的TCP服務器模型

到目前爲止,我已經編寫了一個簡單的測試應用程序,其中包含一個用於與客戶端進行通信的GUI和類。主要的GUI類創建通信類的一個實例。我在BackgroundWorker中調用了socket.accept,並試圖將連接的套接字傳遞迴RunWorkerCompletedEventArgs.Result中的通信類。這一直沒有奏效。我可以打破DoWork方法並查看套接字已連接。然後,我將DoWorkEventArgs.Result設置爲連接的套接字並嘗試將其傳遞迴通信類。在RunWorkerCompleted方法中,套接字不再連接。

我可能對如何爲單個客戶端實現TCP服務器有錯誤的想法。我見過的所有例子都是爲多個客戶設計的,但我將會處理一個客戶。我無法控制客戶端,只是試圖與之通信。

如何將連接的套接字從BackgroundWorker傳遞迴主類,或者更好地構造代碼是我需要的。

更新:

我不控制客戶端。它是一個嵌入式Linux設備。協議非常簡單。大小頭部,後跟數據字節。

目標是.NET 2.0。看來WCF只能在.NET 3.0及更高版本上使用。

更新:

我的代碼將被髮送命令給客戶端和接收數據的後面。我的代碼將是一個需要不斷髮送/接收數據的長時間運行的應用程序。

+1

爲什麼需要手動編程套接字?你不想使用WCF嗎? – abatishchev 2012-07-06 18:45:24

+0

通常,單個或多個客戶端之間的服務器沒有區別。您可以爲每個客戶端提供更高的負載。 – abatishchev 2012-07-06 18:47:03

+0

我建議嘗試'任務並行庫'而不是BGW。 – abatishchev 2012-07-06 18:47:34

回答

0

當您問到其他設計思路時,我的建議(我曾在Java和.NET中使用過這種模式)在過去的4年中在我的項目中證明它工作得很好!) 主要思想是:你不應該把你的套接字放回主類。你的後臺工作者應該阻塞等待客戶端的套接字,一旦它獲得一個連接,它會循環並從客戶端讀取數據。後臺工作人員將通過thread safe queue將收到的數據包(二進制格式,不要在這裏解析數據,因爲它應該是主類的責任)通知主類。主類可以循環(或更好地使用blocking queue)並通過後臺工作進程處理來自客戶端的所有新消息。

這樣你就可以將你的代碼分成兩個不同的層。工作人員負責與客戶和主要客戶談話,其責任是瞭解客戶說什麼並且有選擇地回覆(仍然通過工人)

編輯從您的編輯中,我看到您正在.NET2.0。不幸的是,這個版本的框架沒有線程安全阻塞隊列,因爲它們是在.NET4中引入的。仍然可以找到許多基於.NET2的線程安全隊列實現。

+0

Queue.Synchronized在.Net 2.0中可用。 [鏈接] http://msdn.microsoft.com/en-us/library/system.collections.queue.synchronized(v = vs.80).aspx我會通知事件的主線程,或有一個循環檢查排隊新的數據包? – 2012-07-06 20:25:25

+0

@JamesCrow對不起,我的意思是阻塞隊列不是線程安全隊列:) – GETah 2012-07-06 20:31:41

+0

我應該能夠使用BackgroundWorker ReportProgress方法通知主線程新消息已到達。我正在修改我的通信類,以便在.Net 2.0中試用。 – 2012-07-06 20:42:30