diff --git a/Pilz.Networking/ConnectionManagerBase.vb b/Pilz.Networking/ConnectionManagerBase.vb
index c3b4e7d..1f1dc1d 100644
--- a/Pilz.Networking/ConnectionManagerBase.vb
+++ b/Pilz.Networking/ConnectionManagerBase.vb
@@ -4,7 +4,10 @@ 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
@@ -31,6 +34,7 @@ Public MustInherit Class ConnectionManagerBase
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)
@@ -45,21 +49,108 @@ Public MustInherit Class ConnectionManagerBase
End Sub
Protected Sub ProcessRetrivedData(senderIP As String, buf As Byte())
- Dim contentstring As String = Text.Encoding.Default.GetString(buf)
- Dim content As Object = Nothing
- Dim cmd As String = String.Empty
+ 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
- Try
- Dim res = DecodeFromBytes(buf)
- cmd = res.cmd
- content = res.content
- Catch ex As Exception
- End Try
+ Dim dataID As Integer = readInteger(0)
+ Dim packageID As Integer = readInteger(4)
+ Dim packageCount As Integer = readInteger(8)
+ Dim resolveData As Boolean = True
- RaiseRetriveData(senderIP, cmd, content)
+ '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
- Protected Shared Function EncodeToBytes(cmd As String, content As Object, useAssemblyQualifiedName As Boolean) As Byte()
+ 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.AddRange({(value >> 24) And &HFF, (value >> 16) And &HFF, (value >> 8) And &HFF, 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
@@ -81,7 +172,7 @@ Public MustInherit Class ConnectionManagerBase
Return buf
End Function
- Protected Shared Function DecodeFromBytes(buf As Byte()) As (cmd As String, content As Object)
+ 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)
@@ -98,11 +189,4 @@ Public MustInherit Class ConnectionManagerBase
Return (cmd, content)
End Function
- Public Sub Send(empfängerIP As String, cmd As String, content As Object)
- Dim ep As New IPEndPoint(GetIPFromHost(empfängerIP).MapToIPv4, Port)
- Dim buf As Byte() = EncodeToBytes(cmd, content, UseAssemblyQualifiedName)
-
- SendData(ep, buf)
- End Sub
-
End Class
diff --git a/Pilz.Networking/TCPManager.vb b/Pilz.Networking/TCPManager.vb
index bbe1fb3..801dcf9 100644
--- a/Pilz.Networking/TCPManager.vb
+++ b/Pilz.Networking/TCPManager.vb
@@ -23,9 +23,6 @@ Public Class TCPManager
End If
End Sub
- '''
- ''' Stop listening on given port.
- '''
Public Overrides Sub [Stop]()
If IsListening Then
IsListening = False
@@ -33,6 +30,10 @@ Public Class TCPManager
End If
End Sub
+ Protected Overrides Function GetBufferSize() As Integer
+ Return BufferSize
+ End Function
+
Private Sub CheckRetriveData()
Do While IsListening
If listener.Pending Then
diff --git a/Pilz.Networking/UDPManager.vb b/Pilz.Networking/UDPManager.vb
index 42ea9c6..99dba2e 100644
--- a/Pilz.Networking/UDPManager.vb
+++ b/Pilz.Networking/UDPManager.vb
@@ -12,7 +12,7 @@ Public Class UDPManager
Private listenTask As Task = Nothing
Private ReadOnly cancelTokenSource As New CancellationTokenSource
Private ReadOnly cancelToken As CancellationToken = cancelTokenSource.Token
- Public ReadOnly Property MaxBufferSize As Integer = &H10000
+ Public ReadOnly Property MaxBufferSize As Integer = 8192
Public Sub New(port As Integer)
MyBase.New(port)
@@ -43,9 +43,6 @@ Public Class UDPManager
End Sub)
End Sub
- '''
- ''' Stop listening on given port.
- '''
Public Overrides Sub [Stop]()
If IsListening Then
IsListening = False
@@ -54,6 +51,10 @@ Public Class UDPManager
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()