automaticly send large data as packages

This commit is contained in:
schedpas
2020-06-09 09:35:06 +02:00
parent 6e33874df6
commit bf77505f42
3 changed files with 112 additions and 26 deletions

View File

@@ -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

View File

@@ -23,9 +23,6 @@ Public Class TCPManager
End If
End Sub
''' <summary>
''' Stop listening on given port.
''' </summary>
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

View File

@@ -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
''' <summary>
''' Stop listening on given port.
''' </summary>
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()