From 1932443a20a6723199b402ee3c36ce99aeaa494b Mon Sep 17 00:00:00 2001 From: Pilzinsel64 Date: Wed, 14 Aug 2024 13:49:46 +0200 Subject: [PATCH] convert to C# --- Pilz.Networking/ConnectionManagerBase.cs | 206 ++++++++++++++++++ Pilz.Networking/ConnectionManagerBase.vb | 196 ----------------- .../My Project/Application.Designer.vb | 13 -- Pilz.Networking/My Project/Application.myapp | 10 - .../My Project/Resources.Designer.vb | 63 ------ Pilz.Networking/My Project/Resources.resx | 117 ---------- Pilz.Networking/NetworkFeatures.cs | 62 ++++++ Pilz.Networking/NetworkFeatures.vb | 54 ----- Pilz.Networking/Pilz.Networking.csproj | 17 ++ Pilz.Networking/Pilz.Networking.vbproj | 75 ------- Pilz.Networking/TCPManager.cs | 78 +++++++ Pilz.Networking/TCPManager.vb | 77 ------- Pilz.Networking/UDPManager.cs | 83 +++++++ Pilz.Networking/UDPManager.vb | 91 -------- Pilz.sln | 18 +- 15 files changed, 455 insertions(+), 705 deletions(-) create mode 100644 Pilz.Networking/ConnectionManagerBase.cs delete mode 100644 Pilz.Networking/ConnectionManagerBase.vb delete mode 100644 Pilz.Networking/My Project/Application.Designer.vb delete mode 100644 Pilz.Networking/My Project/Application.myapp delete mode 100644 Pilz.Networking/My Project/Resources.Designer.vb delete mode 100644 Pilz.Networking/My Project/Resources.resx create mode 100644 Pilz.Networking/NetworkFeatures.cs delete mode 100644 Pilz.Networking/NetworkFeatures.vb create mode 100644 Pilz.Networking/Pilz.Networking.csproj delete mode 100644 Pilz.Networking/Pilz.Networking.vbproj create mode 100644 Pilz.Networking/TCPManager.cs delete mode 100644 Pilz.Networking/TCPManager.vb create mode 100644 Pilz.Networking/UDPManager.cs delete mode 100644 Pilz.Networking/UDPManager.vb diff --git a/Pilz.Networking/ConnectionManagerBase.cs b/Pilz.Networking/ConnectionManagerBase.cs new file mode 100644 index 0000000..3a09362 --- /dev/null +++ b/Pilz.Networking/ConnectionManagerBase.cs @@ -0,0 +1,206 @@ +using Newtonsoft.Json.Linq; +using System.Data; +using System.Net; + +namespace Pilz.Networking; + +public abstract class ConnectionManagerBase(int port) +{ + private const int HEADER_LENGTH = 12; + + private bool listening = false; + private readonly Dictionary> dicData = []; + + public int Port { get; private set; } = port; + public bool UseAssemblyQualifiedName { get; set; } = false; + + public event RetriveDataEventHandler RetriveData; + + public delegate void RetriveDataEventHandler(ConnectionManagerBase manager, string senderIP, string cmd, object content); + + public bool IsListening + { + get => listening; + protected set => listening = value; + } + + ~ConnectionManagerBase() + { + Stop(); + } + + public abstract void Start(); + public abstract void Stop(); + protected abstract void SendData(IPEndPoint endPoint, byte[] data); + protected abstract int GetBufferSize(); + + public virtual void Send(string empfängerIP, string cmd) + { + Send(empfängerIP, cmd, string.Empty); + } + + public virtual void Send(string empfängerIP, string cmd, string info) + { + Send(empfängerIP, cmd, (object)info); + } + + private void RaiseRetriveData(string senderIP, string cmd, object content) + { + RetriveData?.Invoke(this, senderIP, cmd, content); + } + + protected void ProcessRetrivedData(string senderIP, byte[] buf) + { + int readInteger(int index) => buf[index] << 24 | buf[index + 1] << 16 | buf[index + 2] << 8 | buf[index + 3]; + + int dataID = readInteger(0); + int packageID = readInteger(4); + int packageCount = readInteger(8); + bool resolveData = true; + + // Remember data + byte[] data = buf.Skip(HEADER_LENGTH).ToArray(); + Dictionary dicMyData; + + if (dicData.ContainsKey(dataID)) + { + dicMyData = dicData[dataID]; + if (dicMyData.ContainsKey(packageID)) + dicMyData[packageID] = data; + else + dicMyData.Add(packageID, data); + } + else + { + dicMyData = new Dictionary() { { packageID, data } }; + dicData.Add(dataID, dicMyData); + } + + if (dicMyData.Count < packageCount) + resolveData = false; + + // Resolve Data + if (resolveData) + { + dicMyData ??= dicData[dataID]; + var myData = new List(); + foreach (var kvp in dicMyData.OrderBy(n => n.Key)) + myData.AddRange(kvp.Value); + dicMyData.Remove(dataID); + + object content = null; + string cmd = string.Empty; + try + { + var res = DecodeFromBytes(myData.ToArray()); + cmd = res.cmd; + content = res.content; + } + catch (Exception) + { + } + + RaiseRetriveData(senderIP, cmd, content); + } + } + private Random _Send_rnd = new(); + + public void Send(string empfängerIP, string cmd, object content) + { + var ep = new IPEndPoint(NetworkFeatures.GetIPFromHost(empfängerIP).MapToIPv4(), Port); + var finalBuffer = new List(); + int maxBufferSize = GetBufferSize(); + int maxDataSize = maxBufferSize - HEADER_LENGTH; + byte[] data = EncodeToBytes(cmd, content, UseAssemblyQualifiedName); + int dataID = _Send_rnd.Next(); + + // Some methods for later user + void send() => SendData(ep, finalBuffer.ToArray()); + void addInteger(int value) + { + finalBuffer.Add((byte)(value >> 24 & 0xFF)); + finalBuffer.Add((byte)(value >> 16 & 0xFF)); + finalBuffer.Add((byte)(value >> 8 & 0xFF)); + finalBuffer.Add((byte)(value & 0xFF)); + }; + void addHeader(int packageID, int packagesCount) + { + addInteger(dataID); // Data ID + addInteger(packageID); // Package ID + addInteger(packagesCount); // Packages Count + }; + + // Send data (this if statement and else content might be useless) + if (data.Length > maxDataSize) + { + int curIndex = 0; + int curID = 0; + int packagesCount = (int)Math.Round(Math.Ceiling(data.Length / (double)maxDataSize)); + + while (curIndex < data.Length) + { + finalBuffer.Clear(); + addHeader(curID, packagesCount); + for (int i = 1, loopTo = maxDataSize; i <= loopTo; i++) + { + if (curIndex < data.Length) + { + finalBuffer.Add(data[curIndex]); + curIndex += 1; + } + } + send(); + curID += 1; + } + } + else + { + addHeader(0, 1); + finalBuffer.AddRange(data); + send(); + } + } + + private static byte[] EncodeToBytes(string cmd, object content, bool useAssemblyQualifiedName) + { + var ms = new MemoryStream(); + var bw = new BinaryWriter(ms); + var obj = new JObject + { + // Write header + ["Cmd"] = cmd, + ["ContentType"] = useAssemblyQualifiedName ? (content?.GetType()?.AssemblyQualifiedName) : (content?.GetType()?.ToString()), + + // Content + ["Content"] = JToken.FromObject(content) + }; + + // Write Json to MemoryStream + bw.Write(System.Text.Encoding.Default.GetBytes(obj.ToString())); + + // Get Buffer Bytes + byte[] buf = ms.ToArray(); + ms.Close(); + + return buf; + } + + private static (string cmd, object content) DecodeFromBytes(byte[] buf) + { + string contentstring = System.Text.Encoding.Default.GetString(buf); + object content = null; + var contentobj = JObject.Parse(contentstring); + + string cmd = (string)contentobj["Cmd"]; + string contenttypestring = (string)contentobj["ContentType"]; + var contentlinq = contentobj["Content"]; + + if (!string.IsNullOrEmpty(contenttypestring)) + { + var contenttype = Type.GetType(contenttypestring); + content = contentlinq.ToObject(contenttype); + } + + return (cmd, content); + } +} \ No newline at end of file diff --git a/Pilz.Networking/ConnectionManagerBase.vb b/Pilz.Networking/ConnectionManagerBase.vb deleted file mode 100644 index 87c5088..0000000 --- a/Pilz.Networking/ConnectionManagerBase.vb +++ /dev/null @@ -1,196 +0,0 @@ -Imports System.IO -Imports System.Net - -Imports Newtonsoft.Json.Linq - -Public MustInherit Class ConnectionManagerBase - - Private Const HEADER_LENGTH As Integer = 12 - - Private listening As Boolean = False - Private ReadOnly dicData As New Dictionary(Of Integer, Dictionary(Of Integer, Byte())) - - Public ReadOnly Property Port As Integer - Public Property UseAssemblyQualifiedName As Boolean = False - - Public Event RetriveData(manager As ConnectionManagerBase, senderIP As String, cmd As String, content As Object) - - Public Property IsListening As Boolean - Get - Return listening - End Get - Protected Set(value As Boolean) - listening = value - End Set - End Property - - Public Sub New(port As Integer) - Me.Port = port - End Sub - - Protected Overrides Sub Finalize() - [Stop]() - End Sub - - Public MustOverride Sub Start() - Public MustOverride Sub [Stop]() - Protected MustOverride Sub SendData(endPoint As IPEndPoint, data As Byte()) - Protected MustOverride Function GetBufferSize() As Integer - - Public Overridable Sub Send(empfängerIP As String, cmd As String) - Send(empfängerIP, cmd, String.Empty) - End Sub - - Public Overridable Sub Send(empfängerIP As String, cmd As String, info As String) - Send(empfängerIP, cmd, CObj(info)) - End Sub - - Private Sub RaiseRetriveData(senderIP As String, cmd As String, content As Object) - RaiseEvent RetriveData(Me, senderIP, cmd, content) - End Sub - - Protected Sub ProcessRetrivedData(senderIP As String, buf As Byte()) - Dim readInteger = - Function(index As Integer) As Integer - Return (CInt(buf(index)) << 24) Or (CInt(buf(index + 1)) << 16) Or (CInt(buf(index + 2)) << 8) Or buf(index + 3) - End Function - - Dim dataID As Integer = readInteger(0) - Dim packageID As Integer = readInteger(4) - Dim packageCount As Integer = readInteger(8) - Dim resolveData As Boolean = True - - 'Remember data - Dim data As Byte() = buf.Skip(HEADER_LENGTH).ToArray - Dim dicMyData As Dictionary(Of Integer, Byte()) - - If dicData.ContainsKey(dataID) Then - dicMyData = dicData(dataID) - If dicMyData.ContainsKey(packageID) Then - dicMyData(packageID) = data - Else - dicMyData.Add(packageID, data) - End If - Else - dicMyData = New Dictionary(Of Integer, Byte()) From {{packageID, data}} - dicData.Add(dataID, dicMyData) - End If - - If dicMyData.Count < packageCount Then - resolveData = False - End If - - 'Resolve Data - If resolveData Then - If dicMyData Is Nothing Then - dicMyData = dicData(dataID) - End If - Dim myData As New List(Of Byte) - For Each kvp In dicMyData.OrderBy(Function(n) n.Key) - myData.AddRange(kvp.Value) - Next - dicMyData.Remove(dataID) - - Dim content As Object = Nothing - Dim cmd As String = String.Empty - Try - Dim res = DecodeFromBytes(myData.ToArray) - cmd = res.cmd - content = res.content - Catch ex As Exception - End Try - - RaiseRetriveData(senderIP, cmd, content) - End If - End Sub - - Public Sub Send(empfängerIP As String, cmd As String, content As Object) - Static rnd As New Random - Dim ep As New IPEndPoint(GetIPFromHost(empfängerIP).MapToIPv4, Port) - Dim finalBuffer As New List(Of Byte) - Dim maxBufferSize As Integer = GetBufferSize() - Dim maxDataSize As Integer = maxBufferSize - HEADER_LENGTH - Dim data As Byte() = EncodeToBytes(cmd, content, UseAssemblyQualifiedName) - Dim dataID As Integer = rnd.Next - - 'Some methods for later user - Dim send = Sub() SendData(ep, finalBuffer.ToArray) - Dim addInteger = - Sub(value As Integer) - finalBuffer.Add((value >> 24) And &HFF) - finalBuffer.Add((value >> 16) And &HFF) - finalBuffer.Add((value >> 8) And &HFF) - finalBuffer.Add(value And &HFF) - End Sub - Dim addHeader = - Sub(packageID As Integer, packagesCount As Integer) - addInteger(dataID) 'Data ID - addInteger(packageID) 'Package ID - addInteger(packagesCount) 'Packages Count - End Sub - - 'Send data (this if statement and else content might be useless) - If data.Length > maxDataSize Then - Dim curIndex As Integer = 0 - Dim curID As Integer = 0 - Dim packagesCount As Integer = Math.Ceiling(data.Length / maxDataSize) - - Do While curIndex < data.Length - finalBuffer.Clear() - addHeader(curID, packagesCount) - For i As Integer = 1 To maxDataSize - If curIndex < data.Length Then - finalBuffer.Add(data(curIndex)) - curIndex += 1 - End If - Next - send() - curID += 1 - Loop - Else - addHeader(0, 1) - finalBuffer.AddRange(data) - send() - End If - End Sub - - Private Shared Function EncodeToBytes(cmd As String, content As Object, useAssemblyQualifiedName As Boolean) As Byte() - Dim ms As New MemoryStream() - Dim bw As New BinaryWriter(ms) - Dim obj As New JObject - - 'Write header - obj("Cmd") = cmd - obj("ContentType") = If(useAssemblyQualifiedName, content?.GetType?.AssemblyQualifiedName, content?.GetType?.ToString) - - 'Content - obj("Content") = JToken.FromObject(content) - - 'Write Json to MemoryStream - bw.Write(Text.Encoding.Default.GetBytes(obj.ToString)) - - 'Get Buffer Bytes - Dim buf As Byte() = ms.ToArray - ms.Close() - - Return buf - End Function - - Private Shared Function DecodeFromBytes(buf As Byte()) As (cmd As String, content As Object) - Dim contentstring As String = Text.Encoding.Default.GetString(buf) - Dim content As Object = Nothing - Dim contentobj As JObject = JObject.Parse(contentstring) - - Dim cmd As String = contentobj("Cmd") - Dim contenttypestring As String = contentobj("ContentType") - Dim contentlinq As JToken = contentobj("Content") - - If Not String.IsNullOrEmpty(contenttypestring) Then - Dim contenttype As Type = Type.GetType(contenttypestring) - content = contentlinq.ToObject(contenttype) - End If - - Return (cmd, content) - End Function - -End Class diff --git a/Pilz.Networking/My Project/Application.Designer.vb b/Pilz.Networking/My Project/Application.Designer.vb deleted file mode 100644 index 8ab460b..0000000 --- a/Pilz.Networking/My Project/Application.Designer.vb +++ /dev/null @@ -1,13 +0,0 @@ -'------------------------------------------------------------------------------ -' -' Dieser Code wurde von einem Tool generiert. -' Laufzeitversion:4.0.30319.42000 -' -' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -' der Code erneut generiert wird. -' -'------------------------------------------------------------------------------ - -Option Strict On -Option Explicit On - diff --git a/Pilz.Networking/My Project/Application.myapp b/Pilz.Networking/My Project/Application.myapp deleted file mode 100644 index 758895d..0000000 --- a/Pilz.Networking/My Project/Application.myapp +++ /dev/null @@ -1,10 +0,0 @@ - - - false - false - 0 - true - 0 - 1 - true - diff --git a/Pilz.Networking/My Project/Resources.Designer.vb b/Pilz.Networking/My Project/Resources.Designer.vb deleted file mode 100644 index efa259c..0000000 --- a/Pilz.Networking/My Project/Resources.Designer.vb +++ /dev/null @@ -1,63 +0,0 @@ -'------------------------------------------------------------------------------ -' -' Dieser Code wurde von einem Tool generiert. -' Laufzeitversion:4.0.30319.42000 -' -' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn -' der Code erneut generiert wird. -' -'------------------------------------------------------------------------------ - -Option Strict On -Option Explicit On - -Imports System - -Namespace My.Resources - - 'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert - '-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert. - 'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen - 'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu. - ''' - ''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. - ''' - _ - Friend Module Resources - - Private resourceMan As Global.System.Resources.ResourceManager - - Private resourceCulture As Global.System.Globalization.CultureInfo - - ''' - ''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. - ''' - _ - Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager - Get - If Object.ReferenceEquals(resourceMan, Nothing) Then - Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("Pilz.Networking.Resources", GetType(Resources).Assembly) - resourceMan = temp - End If - Return resourceMan - End Get - End Property - - ''' - ''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle - ''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. - ''' - _ - Friend Property Culture() As Global.System.Globalization.CultureInfo - Get - Return resourceCulture - End Get - Set - resourceCulture = value - End Set - End Property - End Module -End Namespace diff --git a/Pilz.Networking/My Project/Resources.resx b/Pilz.Networking/My Project/Resources.resx deleted file mode 100644 index af7dbeb..0000000 --- a/Pilz.Networking/My Project/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/Pilz.Networking/NetworkFeatures.cs b/Pilz.Networking/NetworkFeatures.cs new file mode 100644 index 0000000..6168b17 --- /dev/null +++ b/Pilz.Networking/NetworkFeatures.cs @@ -0,0 +1,62 @@ +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; + +namespace Pilz.Networking; + +public static class NetworkFeatures +{ + public static IPAddress GetIPFromHost(string hostName) + { + return Dns.GetHostAddresses(hostName).FirstOrDefault(n => n.AddressFamily == AddressFamily.InterNetwork); + } + + public static object GetHostFromIP(string ip) + { + return Dns.GetHostEntry(ip)?.HostName; + } + + public static UnicastIPAddressInformation GetLocalIPInformations() + { + UnicastIPAddressInformation addr = null; + + foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces()) + { + if (addr is null && adapter.OperationalStatus == OperationalStatus.Up && adapter.NetworkInterfaceType != NetworkInterfaceType.Tunnel && adapter.NetworkInterfaceType != NetworkInterfaceType.Loopback) + { + foreach (UnicastIPAddressInformation uni in adapter.GetIPProperties().UnicastAddresses) + { + if (addr is null && uni.Address.AddressFamily == AddressFamily.InterNetwork) + addr = uni; + } + } + } + + return addr; + } + + public static IPAddress GetLocalIPAddress() + { + return GetLocalIPInformations()?.Address; + } + + public static IPAddress GetLocalIPv4Mask() + { + return GetLocalIPInformations()?.IPv4Mask; + } + + public static IPAddress GetLocalBoradcastIP(UnicastIPAddressInformation ipInfo) + { + IPAddress ip = null; + byte[] myIPBytes = ipInfo.Address.GetAddressBytes(); + byte[] subnetBytes = ipInfo.IPv4Mask.GetAddressBytes(); + byte[] broadcastBytes = new byte[myIPBytes.Length]; + + for (int i = 0, loopTo = subnetBytes.Length - 1; i <= loopTo; i++) + broadcastBytes[i] = (byte)(myIPBytes[i] | ~subnetBytes[i]); + + ip = new IPAddress(broadcastBytes); + + return ip; + } +} \ No newline at end of file diff --git a/Pilz.Networking/NetworkFeatures.vb b/Pilz.Networking/NetworkFeatures.vb deleted file mode 100644 index 3c2f5df..0000000 --- a/Pilz.Networking/NetworkFeatures.vb +++ /dev/null @@ -1,54 +0,0 @@ -Imports System.Net -Imports System.Net.NetworkInformation -Imports System.Net.Sockets - -Public Module NetworkFeatures - - Public Function GetIPFromHost(hostName As String) As IPAddress - Return Dns.GetHostAddresses(hostName).FirstOrDefault(Function(n) n.AddressFamily = AddressFamily.InterNetwork) - End Function - - Public Function GetHostFromIP(ip As String) - Return Dns.GetHostEntry(ip)?.HostName - End Function - - Public Function GetLocalIPInformations() As UnicastIPAddressInformation - Dim addr As UnicastIPAddressInformation = Nothing - - For Each adapter As NetworkInterface In NetworkInterface.GetAllNetworkInterfaces - If addr Is Nothing AndAlso adapter.OperationalStatus = OperationalStatus.Up AndAlso adapter.NetworkInterfaceType <> NetworkInterfaceType.Tunnel AndAlso adapter.NetworkInterfaceType <> NetworkInterfaceType.Loopback Then - For Each uni As UnicastIPAddressInformation In adapter.GetIPProperties.UnicastAddresses - If addr Is Nothing AndAlso uni.Address.AddressFamily = AddressFamily.InterNetwork Then - addr = uni - End If - Next - End If - Next - - Return addr - End Function - - Public Function GetLocalIPAddress() As IPAddress - Return GetLocalIPInformations()?.Address - End Function - - Public Function GetLocalIPv4Mask() As IPAddress - Return GetLocalIPInformations()?.IPv4Mask - End Function - - Public Function GetLocalBoradcastIP(ipInfo As UnicastIPAddressInformation) As IPAddress - Dim ip As IPAddress = Nothing - Dim myIPBytes As Byte() = ipInfo.Address.GetAddressBytes - Dim subnetBytes As Byte() = ipInfo.IPv4Mask.GetAddressBytes - Dim broadcastBytes As Byte() = New Byte(myIPBytes.Length - 1) {} - - For i As Integer = 0 To subnetBytes.Length - 1 - broadcastBytes(i) = myIPBytes(i) Or Not subnetBytes(i) - Next - - ip = New IPAddress(broadcastBytes) - - Return ip - End Function - -End Module diff --git a/Pilz.Networking/Pilz.Networking.csproj b/Pilz.Networking/Pilz.Networking.csproj new file mode 100644 index 0000000..ba2bb7b --- /dev/null +++ b/Pilz.Networking/Pilz.Networking.csproj @@ -0,0 +1,17 @@ + + + + Windows + net8.0-windows + latest + enable + + + + + + + + + + \ No newline at end of file diff --git a/Pilz.Networking/Pilz.Networking.vbproj b/Pilz.Networking/Pilz.Networking.vbproj deleted file mode 100644 index d063837..0000000 --- a/Pilz.Networking/Pilz.Networking.vbproj +++ /dev/null @@ -1,75 +0,0 @@ - - - Windows - net6.0-windows;net8.0-windows - 42016,41999,42017,42018,42019,42032,42036,42020,42021,42022 - Pilz.Networking.xml - true - true - - - true - - - false - - - On - - - Binary - - - Off - - - On - - - 2.0.0 - - - - - - - - - - - - - - - - - - - - - - - True - Application.myapp - - - True - True - Resources.resx - - - - - VbMyResourcesResXFileCodeGenerator - Resources.Designer.vb - My.Resources - Designer - - - - - MyApplicationCodeGenerator - Application.Designer.vb - - - \ No newline at end of file diff --git a/Pilz.Networking/TCPManager.cs b/Pilz.Networking/TCPManager.cs new file mode 100644 index 0000000..4d4dbe3 --- /dev/null +++ b/Pilz.Networking/TCPManager.cs @@ -0,0 +1,78 @@ +using System.Net; +using System.Net.Sockets; + +namespace Pilz.Networking; + +public class TCPManager : ConnectionManagerBase +{ + private readonly TcpListener listener; + public int BufferSize { get; set; } = 10240; + + public TCPManager(int port) : base(port) + { + listener = new TcpListener(IPAddress.Any, port); + } + + public override void Start() + { + if (!IsListening) + { + listener.Start(); + IsListening = true; + Task.Run(CheckRetriveData); + } + } + + public override void Stop() + { + if (IsListening) + { + IsListening = false; + listener.Stop(); + } + } + + protected override int GetBufferSize() + { + return BufferSize; + } + + private void CheckRetriveData() + { + while (IsListening) + { + if (listener.Pending()) + { + var tcp = listener.AcceptTcpClient(); + string ip = ((IPEndPoint)tcp.Client.RemoteEndPoint).Address.ToString(); + var Stream = tcp.GetStream(); + byte[] buf = new byte[BufferSize]; + + tcp.ReceiveBufferSize = BufferSize; + Stream.Read(buf, 0, buf.Length); + + tcp.Close(); + + ProcessRetrivedData(ip, buf); + } + } + } + + protected override void SendData(IPEndPoint ep, byte[] buf) + { + var tcp = new TcpClient + { + SendBufferSize = BufferSize + }; + tcp.Connect(ep); + + var stream = tcp.GetStream(); + + // Send Data + stream.Write(buf, 0, buf.Length); + stream.Flush(); + + tcp.Client.Shutdown(SocketShutdown.Both); + tcp.Close(); + } +} \ No newline at end of file diff --git a/Pilz.Networking/TCPManager.vb b/Pilz.Networking/TCPManager.vb deleted file mode 100644 index 96f2bed..0000000 --- a/Pilz.Networking/TCPManager.vb +++ /dev/null @@ -1,77 +0,0 @@ -Imports System.Net - -' Nicht gemergte Änderung aus Projekt "Pilz.Networking (net8.0-windows)" -' Vor: -' Imports System.Net.Sockets -' Imports Newtonsoft.Json.Linq -' Nach: -' Imports System.Net.Sockets -' -' Imports Newtonsoft.Json.Linq -Imports System.Net.Sockets - -Public Class TCPManager - Inherits ConnectionManagerBase - - Private ReadOnly listener As TcpListener - Public Property BufferSize As Integer = 10240 - - Public Sub New(port As Integer) - MyBase.New(port) - listener = New TcpListener(IPAddress.Any, port) - End Sub - - Public Overrides Sub Start() - If Not IsListening Then - listener.Start() - IsListening = True - Task.Run(AddressOf CheckRetriveData) - End If - End Sub - - Public Overrides Sub [Stop]() - If IsListening Then - IsListening = False - listener.Stop() - End If - End Sub - - Protected Overrides Function GetBufferSize() As Integer - Return BufferSize - End Function - - Private Sub CheckRetriveData() - Do While IsListening - If listener.Pending Then - Dim tcp As TcpClient = listener.AcceptTcpClient() - Dim ip As String = CType(tcp.Client.RemoteEndPoint, IPEndPoint).Address.ToString - Dim Stream As NetworkStream = tcp.GetStream - Dim buf As Byte() = New Byte(BufferSize - 1) {} - - tcp.ReceiveBufferSize = BufferSize - Stream.Read(buf, 0, buf.Length) - - tcp.Close() - - ProcessRetrivedData(ip, buf) - End If - Loop - End Sub - - Protected Overrides Sub SendData(ep As IPEndPoint, buf As Byte()) - Dim tcp As New TcpClient - - tcp.SendBufferSize = BufferSize - tcp.Connect(ep) - - Dim stream As NetworkStream = tcp.GetStream() - - 'Send Data - stream.Write(buf, 0, buf.Length) - stream.Flush() - - tcp.Client.Shutdown(SocketShutdown.Both) - tcp.Close() - End Sub - -End Class diff --git a/Pilz.Networking/UDPManager.cs b/Pilz.Networking/UDPManager.cs new file mode 100644 index 0000000..5c7eda5 --- /dev/null +++ b/Pilz.Networking/UDPManager.cs @@ -0,0 +1,83 @@ +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(); + } +} \ No newline at end of file diff --git a/Pilz.Networking/UDPManager.vb b/Pilz.Networking/UDPManager.vb deleted file mode 100644 index ecc5da1..0000000 --- a/Pilz.Networking/UDPManager.vb +++ /dev/null @@ -1,91 +0,0 @@ -Imports System.Net -Imports System.Net.Sockets - -' Nicht gemergte Änderung aus Projekt "Pilz.Networking (net8.0-windows)" -' Vor: -' Imports System.Threading -' Imports Newtonsoft.Json.Linq -' Nach: -' Imports System.Threading -' -' Imports Newtonsoft.Json.Linq -Imports System.Threading - -Public Class UDPManager - Inherits ConnectionManagerBase - - Private ReadOnly client As UdpClient - Private listenTask As Task = Nothing - Private ReadOnly cancelTokenSource As New CancellationTokenSource - Private ReadOnly cancelToken As CancellationToken = cancelTokenSource.Token - Public ReadOnly Property MaxBufferSize As Integer = 8192 - - Public Sub New(port As Integer) - MyBase.New(port) - client = New UdpClient(port) - End Sub - - Protected Overrides Sub Finalize() - MyBase.Finalize() - client.Client.Shutdown(SocketShutdown.Both) - client.Close() - End Sub - - Public Overrides Sub Start() - If Not IsListening Then - StartInternal() - End If - End Sub - - Private Sub StartInternal() - IsListening = True - listenTask = Task.Run( - Sub() - Try - RetriveAnyData(cancelToken) - Catch ex As Exception - IsListening = False - End Try - End Sub) - End Sub - - Public Overrides Sub [Stop]() - If IsListening Then - IsListening = False - cancelTokenSource.Cancel() - listenTask.Wait() - End If - End Sub - - Protected Overrides Function GetBufferSize() As Integer - Return MaxBufferSize - End Function - - Private Sub RetriveAnyData(ct As CancellationToken) - Dim doExit = Sub() ct.ThrowIfCancellationRequested() - Dim receiveTask As Task(Of UdpReceiveResult) = client.ReceiveAsync() - - 'Wait for the data and cancel if requested - receiveTask.Wait(ct) - - Dim buf As Byte() = receiveTask.Result.Buffer - Dim ip As String = receiveTask.Result.RemoteEndPoint.Address.ToString - - doExit() - - ProcessRetrivedData(ip, buf) - - doExit() - - StartInternal() - End Sub - - Protected Overrides Sub SendData(ep As IPEndPoint, buf As Byte()) - Dim udp As New UdpClient - udp.Connect(ep) - udp.Send(buf, buf.Length) - udp.Client.Shutdown(SocketShutdown.Both) - udp.Close() - End Sub - -End Class diff --git a/Pilz.sln b/Pilz.sln index 6c52fbf..ebbb460 100644 --- a/Pilz.sln +++ b/Pilz.sln @@ -25,7 +25,7 @@ Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz.Simple3DFileParser", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pilz.LicenseHelper", "Pilz.LicenseHelper\Pilz.LicenseHelper.csproj", "{67593FF7-C1D1-4529-98C4-61CBD0615F08}" EndProject -Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Pilz.Networking", "Pilz.Networking\Pilz.Networking.vbproj", "{4584B121-09C6-40AC-849B-7E410125EF66}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pilz.Networking", "Pilz.Networking\Pilz.Networking.csproj", "{F7A0304A-C59E-0F5D-06C3-B43F63B2DBC6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Pilz.Cryptography", "Pilz.Cryptography\Pilz.Cryptography.csproj", "{3F5988E6-439E-4A9D-B2C6-47EFFB161AC6}" EndProject @@ -139,14 +139,14 @@ Global {67593FF7-C1D1-4529-98C4-61CBD0615F08}.Release|Any CPU.Build.0 = Release|Any CPU {67593FF7-C1D1-4529-98C4-61CBD0615F08}.Release|x86.ActiveCfg = Release|Any CPU {67593FF7-C1D1-4529-98C4-61CBD0615F08}.Release|x86.Build.0 = Release|Any CPU - {4584B121-09C6-40AC-849B-7E410125EF66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4584B121-09C6-40AC-849B-7E410125EF66}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4584B121-09C6-40AC-849B-7E410125EF66}.Debug|x86.ActiveCfg = Debug|Any CPU - {4584B121-09C6-40AC-849B-7E410125EF66}.Debug|x86.Build.0 = Debug|Any CPU - {4584B121-09C6-40AC-849B-7E410125EF66}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4584B121-09C6-40AC-849B-7E410125EF66}.Release|Any CPU.Build.0 = Release|Any CPU - {4584B121-09C6-40AC-849B-7E410125EF66}.Release|x86.ActiveCfg = Release|Any CPU - {4584B121-09C6-40AC-849B-7E410125EF66}.Release|x86.Build.0 = Release|Any CPU + {F7A0304A-C59E-0F5D-06C3-B43F63B2DBC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7A0304A-C59E-0F5D-06C3-B43F63B2DBC6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7A0304A-C59E-0F5D-06C3-B43F63B2DBC6}.Debug|x86.ActiveCfg = Debug|Any CPU + {F7A0304A-C59E-0F5D-06C3-B43F63B2DBC6}.Debug|x86.Build.0 = Debug|Any CPU + {F7A0304A-C59E-0F5D-06C3-B43F63B2DBC6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7A0304A-C59E-0F5D-06C3-B43F63B2DBC6}.Release|Any CPU.Build.0 = Release|Any CPU + {F7A0304A-C59E-0F5D-06C3-B43F63B2DBC6}.Release|x86.ActiveCfg = Release|Any CPU + {F7A0304A-C59E-0F5D-06C3-B43F63B2DBC6}.Release|x86.Build.0 = Release|Any CPU {3F5988E6-439E-4A9D-B2C6-47EFFB161AC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3F5988E6-439E-4A9D-B2C6-47EFFB161AC6}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F5988E6-439E-4A9D-B2C6-47EFFB161AC6}.Debug|x86.ActiveCfg = Debug|Any CPU