diff --git a/VL.CoreLib/src/IO/Socket/UdpSocketClient.cs b/VL.CoreLib/src/IO/Socket/UdpSocketClient.cs new file mode 100644 index 00000000..231c3236 --- /dev/null +++ b/VL.CoreLib/src/IO/Socket/UdpSocketClient.cs @@ -0,0 +1,58 @@ +using System.Net; +using System.Net.Sockets; +using VL.Core.Import; +using VL.Lib.Basics.Resources; +using VL.Lib.IO.Socket; +using NetSocket = System.Net.Sockets.Socket; +using NetUtils = VL.Lib.IO.Net.NetUtils; + +[assembly: ImportType(typeof(UdpSocket), Category = "IO.Socket.Advanced")] + +namespace VL.Lib.IO.Socket +{ + /// + /// Manages a UDP socket client provider. + /// + [ProcessNode] + public class UdpSocketClient + { + ResourceProviderMonitor FCurrentProvider; + private bool FConnect = false; + private IPEndPoint FRemoteIPEndPoint; + + /// + /// Configures the internally managed socket provider. + /// + /// The remote end point to use. + /// Whether or not to connect the socket. + /// Whether or not the socket is active. + /// A socket provider which can be used by multiple threads in parallel. + public IResourceProvider Update(IPEndPoint remoteEndpoint, bool connect, bool enabled = true) + { + if (!NetUtils.Equals(FRemoteIPEndPoint, remoteEndpoint) || FConnect != connect) + { + FConnect = connect; + FRemoteIPEndPoint = remoteEndpoint; + + FCurrentProvider = ResourceProvider.New(() => + { + var socket = new NetSocket(SocketType.Dgram, ProtocolType.Udp); + socket.ExclusiveAddressUse = false; + socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); + if (connect && remoteEndpoint != null) + socket.Connect(remoteEndpoint); + return socket; + }).ShareInParallel().Monitor(); + } + + if (enabled) + return FCurrentProvider; + return null; + } + + /// + /// Whether or not the socket is open. + /// + public bool IsOpen => FCurrentProvider?.SinkCount > 0; + } +}