繁体   English   中英

C#UDP多个客户端

[英]C# UDP multiple clients

我在.NETMF应用程序中有一个UDP服务器(该解决方案可能与经典.NET Framework 4.5类似,除了没有诸如UdpClient之类的某些类和方法之外)。 我在这样的套接字上“开始监听”:

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

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM