【问题标题】:C# UDP multiple clientsC# UDP 多个客户端
【发布时间】:2013-04-21 15:09:12
【问题描述】:

我在 .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 创建线程,并将它们保持在挂起状态,直到特定 End Point 的数据可用。

请问这个问题有什么解决办法?

感谢您的努力。

更新 自然的方法是:

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

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

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

【问题讨论】:

  • 从您显示的代码来看,这个问题没有意义。你有一个服务器,但你称它为客户端?此外,数据正在进入缓冲区,为什么不能从那里访问它?请澄清。
  • 另外,这是您的代码的全部吗?
  • 您使用的是 A Fez 还是 Netduino?
  • @rmayer06 现在我再次阅读了代码,我承认该类的客户端名称有点混乱,我已经修改并指定了问题。
  • @rmayer06 好吧,除了一些 using 语句、Main 方法和 main 中的代码来创建它的 ServerThreads。

标签: c# .net udp communication


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 2018-01-04
    • 2011-09-30
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 2018-02-04
    相关资源
    最近更新 更多