C#UDP多个客户端

C#UDP多个客户端

问题描述:

我有一个.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

首先,做这样的嵌入式东西时:不要产生线程来处理工作。使用队列数据结构并存储足够的信息,以便您可以响应请求(即包含信息)。使用2个系统线程,一个是IO,另一个是处理响应。让第一个人决定是否在队列中放置一条消息。如果你不这样做,并且每次请求进入时你都会产生一个线程,你将容易受到数据包泛滥和其他DoS攻击;那会吃掉你有限的记忆。如果队列中的软件包数量不止,则停止接受软件包。

让第二个线程在队列上有要处理的包时唤醒。让它准备在另一个队列上发送的响应(如发送邮件)。当队列中没有更多的项目时,它会自己进入睡眠状态。

如果工作是计算密集型的,那么使用Run time Loadable过程来加速工作。