簡體   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