2013-04-27 158 views
0

我有一個.NETMF應用程序中的UDP服務器(該解決方案可能會類似於傳統的.NET Framework 4.5,除了沒有一些類和方法,如UdpClient)。我「開始聽」這樣的插座上:C#UDP多個客戶端

_server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
_server.Bind(ep); 

現在我要接受來自多個線程的數據(每IPEndPoint一個線程)。關鍵是要最大限度地提高速度。 (請注意,我使用.NETMF,因此UdpClient類不可用)。

我有兩個想法。首先是爲每個預期的IPEndPoint創建一個線程並在那裏接受/處理數據。然而問題是,在一個線程接受數據並確定接受的源IP /端口不同於分配給該線程的IP /端口之後,該數據將被丟棄,並且不再適用於其他適當的線程。有沒有簡單的方法來解決這個問題?在這裏看到示例代碼:

using System; 
using Microsoft.SPOT; 
using System.Net; 
using System.Net.Sockets; 
using System.Threading; 

namespace MFConsoleApplication1 
{ 
    internal class ServerThread 
    { 
     internal IPEndPoint EP { get; private set; } 
     internal Socket Server { get; private set; } 
     public ServerThread(IPEndPoint ep, Socket s) 
     { 
      EP = ep; 
      Server = s; 
      new Thread(() => 
      { 
       byte[] buffer = new byte[2048]; 
       int byteCount; 
       EndPoint recvEP = new IPEndPoint(IPAddress.Any, 0); 
       while (true) 
       { 
        byteCount = Server.ReceiveFrom(buffer, ref recvEP); 
        if (!recvEP.Equals(EP)) cotinue; //this makes the thread to ignore 
        // to ignore the data as EP is different,but it throw the data away 

        // Process data 
        Debug.Print(byteCount.ToString()); // For example 
       } 
      }).Start(); 
     } 
    } 
} 

另一個想法是有一個接受數據的線程。當數據塊被接受時,基於源IP /端口,該線程將創建一個新的線程來處理數據。這種方式似乎不太優雅,因爲它需要每秒創建數十或數百個線程。有一點改進可能是爲每個預期的IPEndPoint創建線程,並將它們保持在掛起狀態,直到特定端點的數據可用。

請問這個問題的解決方法是什麼?

謝謝你的努力。

更新 自然的做法是:

_server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); 
_server.Bind(ep); 
while (true) 
{ 
    byteCount = Server.ReceiveFrom(buffer, ref recvEP); 
    // Process data 
    Debug.Print(byteCount.ToString()); // For example 
} 

但是我需要處理髮送者的地址的基礎上的數據。所以,我也許可以加一行像類似的意思:

new Thread(new ParameterizedThreadStart(ProcessData)).Start(recvEP); 

,並得到了一些數據後執行它每一次,但由於服務器收到幾十 - 幾百個每秒的消息這woudn't過於既優雅。

請爲我的問題提出一個最佳解決方案。

+0

從你展示的代碼中,這個問題沒有意義。你有一臺服務器,但你稱它爲客戶端?此外,數據將進入緩衝區,爲什麼你不能從那裏訪問它?請澄清。 – theMayer 2013-04-27 15:23:34

+0

另外,這是你的代碼的_all_? – theMayer 2013-04-27 15:29:10

+0

您使用的是哪種設備?Fez或Netduino? – 2013-04-27 15:38:14

回答

1

首先,做這樣的嵌入式東西時:不要產生線程來處理工作。使用隊列數據結構並存儲足夠的信息,以便您可以響應請求(即包含信息)。使用2個系統線程,一個是IO,另一個是處理響應。讓第一個人決定是否在隊列中放置一條消息。如果你不這樣做,並且每次請求進入時你都會產生一個線程,你將容易受到數據包氾濫和其他DoS攻擊;那會吃掉你有限的記憶。如果隊列中的軟件包數量不止,則停止接受軟件包。

讓第二個線程在隊列上有要處理的包時喚醒。讓它準備在另一個隊列上發送的響應(如發送郵件)。當隊列中沒有更多的項目時,它會自己進入睡眠狀態。

如果工作是計算密集型的,那麼使用Run time Loadable過程來加速工作。