83 lines
1.9 KiB
C#
83 lines
1.9 KiB
C#
using System.Net;
|
|
using System.Net.Sockets;
|
|
|
|
namespace Pilz.Networking;
|
|
|
|
public class UDPManager : ConnectionManagerBase
|
|
{
|
|
private readonly UdpClient client;
|
|
private Task listenTask = null;
|
|
private readonly CancellationTokenSource cancelTokenSource = new();
|
|
private readonly CancellationToken cancelToken;
|
|
public int MaxBufferSize { get; private set; } = 8192;
|
|
|
|
public UDPManager(int port) : base(port)
|
|
{
|
|
cancelToken = cancelTokenSource.Token;
|
|
client = new UdpClient(port);
|
|
}
|
|
|
|
~UDPManager()
|
|
{
|
|
client.Client.Shutdown(SocketShutdown.Both);
|
|
client.Close();
|
|
}
|
|
|
|
public override void Start()
|
|
{
|
|
if (!IsListening)
|
|
{
|
|
StartInternal();
|
|
}
|
|
}
|
|
|
|
private void StartInternal()
|
|
{
|
|
IsListening = true;
|
|
listenTask = Task.Run(() => { try { RetriveAnyData(cancelToken); } catch (Exception ex) { IsListening = false; } });
|
|
}
|
|
|
|
public override void Stop()
|
|
{
|
|
if (IsListening)
|
|
{
|
|
IsListening = false;
|
|
cancelTokenSource.Cancel();
|
|
listenTask.Wait();
|
|
}
|
|
}
|
|
|
|
protected override int GetBufferSize()
|
|
{
|
|
return MaxBufferSize;
|
|
}
|
|
|
|
private void RetriveAnyData(CancellationToken ct)
|
|
{
|
|
void doExit() => ct.ThrowIfCancellationRequested();
|
|
var receiveTask = client.ReceiveAsync();
|
|
|
|
// Wait for the data and cancel if requested
|
|
receiveTask.Wait(ct);
|
|
|
|
byte[] buf = receiveTask.Result.Buffer;
|
|
string ip = receiveTask.Result.RemoteEndPoint.Address.ToString();
|
|
|
|
doExit();
|
|
|
|
ProcessRetrivedData(ip, buf);
|
|
|
|
doExit();
|
|
|
|
StartInternal();
|
|
}
|
|
|
|
protected override void SendData(IPEndPoint ep, byte[] buf)
|
|
{
|
|
var udp = new UdpClient();
|
|
udp.Connect(ep);
|
|
udp.Send(buf, buf.Length);
|
|
udp.Client.Shutdown(SocketShutdown.Both);
|
|
udp.Close();
|
|
}
|
|
} |