c# UDP多客户端

本文关键字:客户端 UDP | 更新日期: 2023-09-27 18:11:04

我在一个。net mf应用程序中有一个UDP服务器(解决方案可能类似于经典的。net Framework 4.5,除了没有一些类和方法,如UdpClient)。我在套接字上"开始监听",像这样:

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

现在我想接受来自多个线程的数据(每个IPEndPoint一个线程)。关键是要使速度最大化。(请注意,我使用。net mf所以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创建线程,并保持它们处于挂起状态,直到特定EndPoint的数据可用。

这个问题的解决方法是什么?

谢谢你的努力。

自然的方法是:

_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);

并在每次接收到一些数据后执行它,但由于服务器每秒接收数十-数百条消息,这也不会太优雅。

请为我的问题提出一个最佳解决方案。

c# UDP多客户端

首先,在做这样的嵌入式东西时:不要仅仅为了处理工作而生成线程。使用队列数据结构并存储足够的信息,以便您可以响应请求(即打包信息)。使用2个系统线程,一个处理IO,一个处理响应。让第一个线程决定是否将消息放入队列。如果你不这样做,你只是在每次请求进来时生成一个线程,你将容易受到包泛滥和其他DoS漏洞的影响;这会消耗你有限的记忆。如果队列中有超过合理数量的包,则停止接受包。

当队列上有包需要处理时,让第二个线程被唤醒。让它准备在另一个队列上发送的响应(如发送邮件)。当队列中没有其他项目时,它将自己置于睡眠状态。

如果工作是计算密集型的,那么使用运行时可加载过程来加速工作。