feat: 实现udp多端口

This commit is contained in:
2025-07-14 14:01:08 +08:00
parent 2894ee24be
commit ca906489c2
9 changed files with 53 additions and 92 deletions

View File

@@ -74,12 +74,8 @@ public class UDPServer
private ConcurrentDictionary<string, ConcurrentQueue<UDPData>> udpData = new ConcurrentDictionary<string, ConcurrentQueue<UDPData>>();
const int parallelTaskNum = 5;
Task[] ReceiveTasks = new Task[parallelTaskNum];
private int runningTaskNum = 0;
private int listenPort;
private UdpClient listener;
private List<UdpClient> listeners = new List<UdpClient>();
private IPEndPoint groupEP;
private bool isRunning = false;
@@ -105,15 +101,19 @@ public class UDPServer
/// Construct a udp server with fixed port
/// </summary>
/// <param name="port"> Device UDP Port </param>
/// <param name="num"> UDP Client Num </param>
/// <returns> UDPServer class </returns>
public UDPServer(int port)
public UDPServer(int port, int num)
{
// Construction
listenPort = port;
this.listenPort = port;
try
{
listener = new UdpClient(listenPort);
groupEP = new IPEndPoint(IPAddress.Any, listenPort);
for (int i = 0; i < num; i++)
{
listeners.Add(new UdpClient(this.listenPort + i));
}
this.groupEP = new IPEndPoint(IPAddress.Any, listenPort);
}
catch (Exception e)
{
@@ -346,54 +346,24 @@ public class UDPServer
return retPack.Value;
}
private void ReceiveHandler(IAsyncResult res)
private void ReceiveHandler(byte[] data, IPEndPoint endPoint)
{
var remoteEP = new IPEndPoint(IPAddress.Any, listenPort);
byte[] bytes = listener.EndReceive(res, ref remoteEP);
// 继续异步接收
if (isRunning)
{
listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
}
else
{
runningTaskNum--;
}
// Handle RemoteEP
if (remoteEP is null)
if (endPoint is null)
{
logger.Debug($"Receive Data from Unknown at {DateTime.Now.ToString()}:");
logger.Debug($" Original Data : {BitConverter.ToString(bytes).Replace("-", " ")}");
logger.Debug($" Original Data : {BitConverter.ToString(data).Replace("-", " ")}");
return;
}
// 异步处理数据包
Task.Run(() =>
{
var udpData = RecordUDPData(bytes, remoteEP, Convert.ToInt32(bytes[1]));
var udpData = RecordUDPData(data, endPoint, Convert.ToInt32(data[1]));
PrintData(udpData);
});
}
private bool SendBytes(IPEndPoint endPoint, byte[] buf)
{
var sendLen = listener.Send(buf, endPoint);
if (sendLen == buf.Length) { return true; }
else { return false; }
}
private bool SendString(IPEndPoint endPoint, string text)
{
byte[] buf = Encoding.ASCII.GetBytes(text);
var sendLen = listener.Send(buf, endPoint);
if (sendLen == buf.Length) { return true; }
else { return false; }
}
private UDPData RecordUDPData(byte[] bytes, IPEndPoint remoteEP, int taskID)
{
var remoteAddress = remoteEP.Address.ToString();
@@ -484,7 +454,7 @@ public class UDPServer
/// <param name="ipAddr">IP地址</param>
/// <param name="taskID">[TODO:parameter]</param>
/// <returns>无</returns>
public async Task ClearUDPData(string ipAddr, int taskID)
public void ClearUDPData(string ipAddr, int taskID)
{
var key = $"{ipAddr}-{taskID}";
if (udpData.TryGetValue(key, out var dataQueue))
@@ -503,19 +473,24 @@ public class UDPServer
this.isRunning = true;
try
{
Task.Run(() =>
foreach (var client in listeners)
{
while (isRunning)
Task.Run(async () =>
{
if (runningTaskNum < parallelTaskNum)
while (this.isRunning)
{
StartReceive();
logger.Debug($"Begin Receive Task, Now Running Num: {runningTaskNum + 1}");
runningTaskNum++;
try
{
UdpReceiveResult result = await client.ReceiveAsync();
ReceiveHandler(result.Buffer, result.RemoteEndPoint);
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
}
}
Task.Delay(100).Wait();
}
});
});
}
}
catch (Exception e)
{
@@ -524,30 +499,16 @@ public class UDPServer
}
}
private void StartReceive(int times = 5)
{
for (int i = 0; i < times; i++)
{
try
{
this.listener.BeginReceive(new AsyncCallback(ReceiveHandler), null);
break; // BeginReceive is async, break after scheduling
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
/// <summary>
/// Close UDP Server
/// </summary>
/// <returns>None</returns>
public void Stop()
{
this.listener.Close();
foreach (var item in listeners)
{
item.Close();
}
this.isRunning = false;
}
}