Modul NetworkArray

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Modul NetworkArray

Beitrag von mk-soft »

Modul zum übertragen von Arrays (Dim) über Netzwerk.

Der Empfang der Daten wird im Thread durchgeführt und an eine Callback-Routine übergeben.
Der Aufbau der Callback-Funktion muss folgenden Aufbau habe:
NewDataCB(SEvent, ConnectionID, *NewData.udtDataset)
Wenn die CallBack-Funktion ungleich Null zurückgibt, werden der empfangene Daten gelöscht.

Für das Senden der Daten gibt es "NetSendStringArray(...), NetSend...
Dazu kann zur Identifizierung eine DataID mit übermittelt werden.

Ein einzelner String in Array darf bei Unicode bis zu 30000 Zeichen enthalten und bei ASCII bis zu 60000 Zeichen.
Wenn der Server in Unicode läuft, muss auch der Client in Unicode laufen.
Bei Verwendung von IntegerArray müssen beide, (Server und Client), als 32Bit oder 64Bit laufen

Update v1.08
- Geändert: Eigene Nummern für Datentype
- Geändert: Validieren vom Header
- Hinzugefügt: NetSendRawData(...)
- Update Beispiele

Update v1.091
- Bugfix für PB (X64) auf MacOS (Probleme mit Dim)

Modul_NetworkArray.pb

Code: Alles auswählen

;-TOP

; Comment: NetworkArray
; Author : mk-soft
; Version: v1.091
; Created: 12.06.2016
; Updated: 02.07.2016
; Link De: http://www.purebasic.fr/german/viewtopic.php?f=8&t=29690
; Link En: http://www.purebasic.fr/english/viewtopic.php?f=12&t=65988

; ***************************************************************************************

;- Begin Declare Module

CompilerIf #PB_Compiler_Thread = 0
  CompilerError "Use Compileroption Threadsafe!"
CompilerEndIf

DeclareModule NetworkArray
  
  Enumeration 1
    #NetStringArray
    #NetByteArray
    #NetIntegerArray
    #NetLongArray
    #NetFloatArray
    #NetDoubleArray
    #NetRawData
  EndEnumeration
  
  Structure udtAny
    StructureUnion
      bVal.b[0]
      wVal.w[0]
      iVal.i[0]
      lVal.l[0]
      fVal.f[0]
      dVal.d[0]
    EndStructureUnion
  EndStructure
  
  Structure udtDataset
    DataID.i
    Type.i
    Array Text.s(0)
    Array Byte.b(0)
    Array Integer.i(0)
    Array Long.l(0)
    Array Float.f(0)
    Array Double.d(0)
    *RawData.udtAny
  EndStructure
  
  Declare BindLogging(Event, Gadget)
  Declare UnBindLogging(Event, Gadget)
  Declare Logging(Info.s)
  
  Declare InitServer(Port, *NewDataCallback = 0, BindedIP.s = "")
  Declare CloseServer(ServerID)
  Declare InitClient(IP.s, Port, *NewDataCallback = 0, Timeout = 0)
  Declare CloseClient(ConnectionID)
  Declare SetServerNewDataCB(ServerID, *NewDataCallback)
  Declare SetClientNewDataCB(ConnectionID, *NewDataCallback)
  Declare NetSendStringArray(ConnectionID, DataID, Array SendData.s(1))
  Declare NetSendByteArray(ConnectionID, DataID, Array SendData.b(1))
  Declare NetSendIntegerArray(ConnectionID, DataID, Array SendData.i(1))
  Declare NetSendLongArray(ConnectionID, DataID, Array SendData.l(1))
  Declare NetSendFloatArray(ConnectionID, DataID, Array SendData.f(1))
  Declare NetSendDoubleArray(ConnectionID, DataID, Array SendData.d(1))
  Declare NetSendRawData(ConnectionID, DataID, *Data.udtAny, SizeOfData)
  
EndDeclareModule

;- Begin Module

Module NetworkArray
  
  EnableExplicit
  
  Global ProtocolID.l = $EFAA2016
  
  ; -----------------------------------------------------------------------------------
  
  Prototype ProtoNewDataCB(SEvent, ConnectionID, *NewData.udtDataset)
  
  ; -----------------------------------------------------------------------------------
  
  ; Size of blockdata without header
  #BlockSizeData = 1024
  #BlockSizeText = 60002 
  
  Structure udtServerList
    ServerID.i
    ThreadID.i
    NewDataCB.ProtoNewDataCB
    ExitServer.i
  EndStructure
  
  Structure udtClientList
    ConnectionID.i
    ThreadID.i
    NewDataCB.ProtoNewDataCB
    ExitClient.i
  EndStructure
  
  Structure udtDataBlock
    ProtocolID.l
    Datalen.l
    DataID.l
    State.w
    Type.w
    Size.l
    Index.l
    Count.l
    pData.udtAny
  EndStructure
  
  Structure udtBuffer
    b.b[$FFFF]
  EndStructure
  
  Structure udtNetData
    Map Dataset.udtDataset()
    ConnectionID.i
    DataOffset.i
    Datalen.i
    StructureUnion
      Receive.udtDataBlock
      Buffer.udtBuffer
    EndStructureUnion
  EndStructure
  
  Structure udtSendBuffer
    StructureUnion
      Send.udtDataBlock
      Buffer.udtBuffer
    EndStructureUnion
  EndStructure
  
  ; -----------------------------------------------------------------------------------
  
  Global LoggingEvent
  Global LoggingGadget
  
  Global LockSend
  
  Threaded NewMap NetData.udtNetData()
  Threaded ReceiveBuffer.udtBuffer
  Threaded SendBuffer.udtSendBuffer
  
  ; -----------------------------------------------------------------------------------
  
  Global NewMap ServerList.udtServerList()
  Global NewMap ClientList.udtClientList()
  
  ; -----------------------------------------------------------------------------------
  
  InitNetwork()
  LockSend = CreateMutex()
  
  ; -----------------------------------------------------------------------------------
  
  Declare ThreadServer(*this.udtServerList)
  Declare ThreadClient(*this.udtClientList)
  
  ; -----------------------------------------------------------------------------------
  
  Procedure Logging(Info.s)
    Protected text.s, *mem
    If LoggingEvent
      text = FormatDate("[%YYYY-%MM-%DD %HH:%II:%SS] ", Date()) + Info
      *mem = AllocateMemory(StringByteLength(text) + SizeOf(character))
      PokeS(*mem, text)
      PostEvent(LoggingEvent, 0, LoggingGadget, 0, *mem)
    EndIf
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure AddLoggingItem()
    Protected gadget, count, *mem
    gadget = EventGadget()
    *mem = EventData()
    If *mem
      If IsGadget(gadget)
        AddGadgetItem(gadget, -1, PeekS(*mem))
        count = CountGadgetItems(gadget)
        If count > 1000
          RemoveGadgetItem(gadget, 0)
          count - 1
        EndIf
        count - 1
        SetGadgetState(gadget, count)
        SetGadgetState(gadget, -1)
      EndIf
      FreeMemory(*mem)
    EndIf
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure BindLogging(Event, Gadget)
    BindEvent(Event, @AddLoggingItem(), 0, Gadget)
    LoggingEvent = Event
    LoggingGadget = Gadget
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure UnbindLogging(Event, Gadget)
    UnbindEvent(Event, @AddLoggingItem(), 0, Gadget)
    LoggingEvent = 0
    LoggingGadget = 0
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure InitServer(Port, *NewDataCallback = 0, BindedIP.s = "")
    Protected ServerID, keyServerID.s
    
    ServerID = CreateNetworkServer(#PB_Any, Port, #PB_Network_TCP, BindedIP)
    If ServerID
      keyServerID = Str(ServerID)
      AddMapElement(ServerList(), keyServerID)
      ServerList()\ServerID = ServerID
      ServerList()\NewDataCB = *NewDataCallback
      ServerList()\ThreadID = CreateThread(@ThreadServer(), @ServerList())
      Logging("Network: Init Server: ID " + Str(ServerID))
    Else
      Logging("Network: Error Init Network Server")
    EndIf
    ProcedureReturn ServerID
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure CloseServer(ServerID)
    Protected keyServerID.s, count
    
    keyServerID = Str(ServerID)
    If FindMapElement(ServerList(), keyServerID)
      Logging("Network: Close Network Server: ID " + keyServerID)
      CloseNetworkServer(ServerID)
      ServerList()\ExitServer = 1
      Repeat
        If ServerList()\ExitServer = 0
          Break
        Else
          count + 1
          If count >= 10
            KillThread(ServerList()\ThreadID)
            Logging("Network: Error - Kill Network Server: ID " + keyServerID)
            Break
          EndIf
        EndIf
        Delay(100)
      ForEver
      DeleteMapElement(ServerList(), keyServerID)
    EndIf
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure InitClient(IP.s, Port, *NewDataCallback = 0, Timeout = 0)
    Protected ConnectionID, keyConnectionID.s
    
    ConnectionID = OpenNetworkConnection(IP, Port, #PB_Network_TCP, Timeout)
    If ConnectionID
      keyConnectionID = Str(ConnectionID)
      AddMapElement(ClientList(), keyConnectionID)
      ClientList()\ConnectionID = ConnectionID
      ClientList()\NewDataCB = *NewDataCallback
      ClientList()\ThreadID = CreateThread(@ThreadClient(), @ClientList())
      Logging("Network: Init Network Connection: ID " + Str(ConnectionID))
    Else
      Logging("Network: Error Init Network Connection")
    EndIf
    ProcedureReturn ConnectionID
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure SetServerNewDataCB(ServerID, *NewDataCallback)
    Protected keyServerID.s
    
    keyServerID = Str(ServerID)
    If FindMapElement(ServerList(), keyServerID)
      ServerList()\NewDataCB = *NewDataCallback
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure SetClientNewDataCB(ConnectionID, *NewDataCallback)
    Protected keyConnectionID.s
    
    keyConnectionID = Str(ConnectionID)
    If FindMapElement(ClientList(), keyConnectionID)
      ClientList()\NewDataCB = *NewDataCallback
      ProcedureReturn #True
    Else
      ProcedureReturn #False
    EndIf
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure CloseClient(ConnectionID)
    Protected keyConnectionID.s, count
    
    keyConnectionID = Str(ConnectionID)
    If FindMapElement(ClientList(), keyConnectionID)
      Logging("Network: Close Network Client: ID " + keyConnectionID)
      CloseNetworkConnection(ConnectionID)
      ClientList()\ExitClient = 1
      Repeat
        If ClientList()\ExitClient = 0
          Break
        Else
          count + 1
          If count >= 10
            KillThread(ClientList()\ThreadID)
            Logging("Network: Error - Kill Network Client: ID " + keyConnectionID)
            Break
          EndIf
        EndIf
        Delay(100)
      ForEver
      DeleteMapElement(ClientList(), keyConnectionID)
    EndIf
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  ; Bugfix MacOS PB v5.42 X64 (DIM) Not use Select Case 
  
  Procedure DimDataset(Map Dataset.udtDataset(), Type, Size)
    Protected result
    
    With Dataset()
      If Type = #NetStringArray
        Dim \Text(Size)
        result = ArraySize(\Text())
      ElseIf Type = #NetByteArray
        Dim \Byte(Size)
        result = ArraySize(\Byte())
      ElseIf Type = #NetIntegerArray
        Dim \Integer(Size)
        result = ArraySize(\Integer())
      ElseIf Type = #NetLongArray
        Dim \Long(Size)
        result = ArraySize(\Long())
      ElseIf Type = #NetFloatArray
        Dim \Float(Size)
        result = ArraySize(\Float())
      ElseIf Type = #NetDoubleArray
        Dim \Double(Size)
        result = ArraySize(\Double())
      ElseIf Type = #NetRawData
        If \RawData
          FreeMemory(\RawData)
        EndIf
        \RawData = AllocateMemory(Size)
        If \RawData
          ProcedureReturn #True
        Else
          ProcedureReturn #False
        EndIf
      EndIf
      If result >= 0
        ProcedureReturn #True
      Else
        ProcedureReturn #False
      EndIf
    EndWith
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure FreeDataset(Map Dataset.udtDataset())
    With Dataset()
      \DataID = 0
      \Type = 0
      FreeArray(\Text())
      FreeArray(\Byte())
      FreeArray(\Integer())
      FreeArray(\Long())
      FreeArray(\Float())
      FreeArray(\Double())
      If \RawData
        FreeMemory(\RawData)
        \RawData = 0
      EndIf
    EndWith
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure NetSendStringArray(ConnectionID, DataID, Array SendData.s(1))
    Protected count, len, index
    
    LockMutex(LockSend)
    
    With SendBuffer\Send
      \ProtocolID = ProtocolID
      \DataID = DataID
      \State = 1
      \Type = #NetStringArray
      \Size = ArraySize(SendData())
      \Count = 1
      For index = 0 To \Size
        If index >= \Size
          \State + 2
        EndIf
        \Index = index
        \Datalen = SizeOf(udtDataBlock) + Len(Senddata(index)) * SizeOf(character) + SizeOf(character)
        PokeS(\pData, Senddata(index))
        count = SendNetworkData(ConnectionID, SendBuffer, \Datalen)
        If count <> \Datalen
          Logging("Network: Error SendStringArray: DataID " + Str(\DataID))
          UnlockMutex(LockSend)
          ProcedureReturn 0
        EndIf
        If \State
          \State = 0
        EndIf
      Next
      
    EndWith
    
    UnlockMutex(LockSend)
    
    ProcedureReturn 1
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure NetSendByteArray(ConnectionID, DataID, Array SendData.b(1))
    Protected count, len, size, index, ofs
    
    LockMutex(LockSend)
    
    With SendBuffer\Send
      size = ArraySize(SendData())
      index = 0
      ofs = 0
      \ProtocolID = ProtocolID
      \DataID = DataID
      \State = 1
      \Type = #NetByteArray
      \Size = size
      \Index = 0
      \Count = 1
      Repeat
        \pData\bVal[ofs] = SendData(index)
        index + 1
        ofs + 1
        If ofs = #BlockSizeData Or index > size
          If index > size
            \State + 2
          EndIf
          \Count = ofs
          \Datalen = SizeOf(udtDataBlock) + SizeOf(byte) * ofs
          count = SendNetworkData(ConnectionID, SendBuffer, \Datalen)
          If count <> \Datalen
            Logging("Network: Error SendByteArray: DataID " + Str(\DataID))
            UnlockMutex(LockSend)
            ProcedureReturn 0
          EndIf
          \Index + ofs
          \State = 0
          ofs = 0
        EndIf
      Until index > size
      
    EndWith
    
    UnlockMutex(LockSend)
    
    ProcedureReturn 1
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure NetSendIntegerArray(ConnectionID, DataID, Array SendData.i(1))
    Protected count, len, size, index, ofs
    
    LockMutex(LockSend)
    
    With SendBuffer\Send
      size = ArraySize(SendData())
      index = 0
      ofs = 0
      \ProtocolID = ProtocolID
      \DataID = DataID
      \State = 1
      \Type = #NetIntegerArray
      \Size = size
      \Index = 0
      \Count = 1
      Repeat
        \pData\iVal[ofs] = SendData(index)
        index + 1
        ofs + 1
        If ofs = #BlockSizeData / SizeOf(integer) Or index > size
          If index > size
            \State + 2
          EndIf
          \Count = ofs
          \Datalen = SizeOf(udtDataBlock) + SizeOf(integer) * ofs
          count = SendNetworkData(ConnectionID, SendBuffer, \Datalen)
          If count <> \Datalen
            Logging("Network: Error SendIntegerArray: DataID " + Str(\DataID))
            UnlockMutex(LockSend)
            ProcedureReturn 0
          EndIf
          \Index + ofs
          \State = 0
          ofs = 0
        EndIf
      Until index > size
      
    EndWith
    
    UnlockMutex(LockSend)
    
    ProcedureReturn 1
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure NetSendLongArray(ConnectionID, DataID, Array SendData.l(1))
    Protected count, len, size, index, ofs
    
    LockMutex(LockSend)
    
    With SendBuffer\Send
      size = ArraySize(SendData())
      index = 0
      ofs = 0
      \ProtocolID = ProtocolID
      \DataID = DataID
      \State = 1
      \Type = #NetLongArray
      \Size = size
      \Index = 0
      \Count = 1
      Repeat
        \pData\lVal[ofs] = SendData(index)
        index + 1
        ofs + 1
        If ofs = #BlockSizeData / SizeOf(long) Or index > size
          If index > size
            \State + 2
          EndIf
          \Count = ofs
          \Datalen = SizeOf(udtDataBlock) + SizeOf(long) * ofs
          count = SendNetworkData(ConnectionID, SendBuffer, \Datalen)
          If count <> \Datalen
            Logging("Network: Error SendIntegerArray: DataID " + Str(\DataID))
            UnlockMutex(LockSend)
            ProcedureReturn 0
          EndIf
          \Index + ofs
          \State = 0
          ofs = 0
        EndIf
      Until index > size
      
    EndWith
    
    UnlockMutex(LockSend)
    
    ProcedureReturn 1
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure NetSendFloatArray(ConnectionID, DataID, Array SendData.f(1))
    Protected count, len, size, index, ofs
    
    LockMutex(LockSend)
    
    With SendBuffer\Send
      size = ArraySize(SendData())
      index = 0
      ofs = 0
      \ProtocolID = ProtocolID
      \DataID = DataID
      \State = 1
      \Type = #NetFloatArray
      \Size = size
      \Index = 0
      \Count = 1
      Repeat
        \pData\fVal[ofs] = SendData(index)
        index + 1
        ofs + 1
        If ofs = #BlockSizeData / SizeOf(float) Or index > size
          If index > size
            \State + 2
          EndIf
          \Count = ofs
          \Datalen = SizeOf(udtDataBlock) + SizeOf(float) * ofs
          count = SendNetworkData(ConnectionID, SendBuffer, \Datalen)
          If count <> \Datalen
            Logging("Network: Error SendIntegerArray: DataID " + Str(\DataID))
            UnlockMutex(LockSend)
            ProcedureReturn 0
          EndIf
          \Index + ofs
          \State = 0
          ofs = 0
        EndIf
      Until index > size
      
    EndWith
    
    UnlockMutex(LockSend)
    
    ProcedureReturn 1
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure NetSendDoubleArray(ConnectionID, DataID, Array SendData.d(1))
    Protected count, len, size, index, ofs
    
    LockMutex(LockSend)
    
    With SendBuffer\Send
      size = ArraySize(SendData())
      index = 0
      ofs = 0
      \ProtocolID = ProtocolID
      \DataID = DataID
      \State = 1
      \Type = #NetDoubleArray
      \Size = size
      \Index = 0
      \Count = 1
      Repeat
        \pData\dVal[ofs] = SendData(index)
        index + 1
        ofs + 1
        If ofs = #BlockSizeData / SizeOf(double) Or index > size
          If index > size
            \State + 2
          EndIf
          \Count = ofs
          \Datalen = SizeOf(udtDataBlock) + SizeOf(double) * ofs
          count = SendNetworkData(ConnectionID, SendBuffer, \Datalen)
          If count <> \Datalen
            Logging("Network: Error SendIntegerArray: DataID " + Str(\DataID))
            UnlockMutex(LockSend)
            ProcedureReturn 0
          EndIf
          \Index + ofs
          \State = 0
          ofs = 0
        EndIf
      Until index > size
      
    EndWith
    
    UnlockMutex(LockSend)
    
    ProcedureReturn 1
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure NetSendRawData(ConnectionID, DataID, *Data.udtAny, SizeOfData)
    Protected count, len, size, index, ofs
    
    LockMutex(LockSend)
    
    With SendBuffer\Send
      size = SizeOfData
      index = 0
      ofs = 0
      \ProtocolID = ProtocolID
      \DataID = DataID
      \State = 1
      \Type = #NetRawData
      \Size = size
      \Index = 0
      \Count = 1
      Repeat
        \pData\bVal[ofs] = *Data\bVal[index]
        index + 1
        ofs + 1
        If ofs = #BlockSizeData Or index > size
          If index > size
            \State + 2
          EndIf
          \Count = ofs
          \Datalen = SizeOf(udtDataBlock) + SizeOf(byte) * ofs
          count = SendNetworkData(ConnectionID, SendBuffer, \Datalen)
          If count <> \Datalen
            Logging("Network: Error SendRawData: DataID " + Str(\DataID))
            UnlockMutex(LockSend)
            ProcedureReturn 0
          EndIf
          \Index + ofs
          \State = 0
          ofs = 0
        EndIf
      Until index > size
      
    EndWith
    
    UnlockMutex(LockSend)
    
    ProcedureReturn 1
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure NetReceiveData(ConnectionID, *NewDataCB.ProtoNewDataCB)
    Protected count, size, ofs, len, index, lbound, ubound, error, keyConnectionID.s, keyData.s
    
    ; Set or Create NetData
    keyConnectionID = Str(ConnectionID)
    If Not FindMapElement(NetData(), keyConnectionID)
      AddMapElement(NetData(), keyConnectionID)
      NetData()\ConnectionID = ConnectionID
      NetData()\DataOffset = 0
      NetData()\Datalen = 0
    EndIf
    
    error = #False
    
    Repeat
      With NetData()
        ; Read header
        If \DataOffset < SizeOf(udtDataBlock)
          count = ReceiveNetworkData(ConnectionID, ReceiveBuffer, SizeOf(udtDataBlock) - \DataOffset)
          If count <= 0
            Logging("Network: Error Receive Data: ID " + keyConnectionID)
            Break
          EndIf
          CopyMemory(ReceiveBuffer, \Receive + \DataOffset, count)
          \DataOffset + count
          If \DataOffset < SizeOf(udtDataBlock)
            Break
          Else
            ; Check header
            If \Receive\ProtocolID <> ProtocolID
              Logging("Network: Error ProtocolID: ID " + keyConnectionID)
              error = #True
              Break
            EndIf
            \Datalen = \Receive\Datalen
            If \Receive\Type = #NetStringArray
              If \Datalen > #BlockSizeText + SizeOf(udtDataBlock)
                Logging("Network: Error Datalen: ID " + keyConnectionID)
                error = #True
                Break
              EndIf
            Else
              If \Datalen > #BlockSizeData + SizeOf(udtDataBlock)
                Logging("Network: Error Datalen: ID " + keyConnectionID)
                error = #True
                Break
              EndIf
            EndIf
          EndIf
          Break
        EndIf
        ; Read data
        count = ReceiveNetworkData(ConnectionID, ReceiveBuffer, \Datalen - \DataOffset)
        If count <= 0
          Logging("Network: Error Receive Data: ID " + keyConnectionID)
          Break
        EndIf
        CopyMemory(ReceiveBuffer, \Receive + \DataOffset, count)
        \DataOffset + count
        If \DataOffset < \Datalen
          Break
        EndIf
        \DataOffset = 0
        \Datalen = 0
      EndWith
      
      ; Daten auswerten
      With NetData()\Receive
        ; Set or Create Dataset over DataID
        keyData = Str(\DataID)
        If Not FindMapElement(NetData()\Dataset(), keyData)
          If Not AddMapElement(NetData()\Dataset(), keyData)
            Logging("Network: Error Out of memory")
            error = #True
            Break
          EndIf
        EndIf
        ; Check first Datablock
        If \State & 1
          If Not DimDataset(NetData()\Dataset(), \Type, \Size)
            Logging("Network: Error Out of memory")
            error = #True
            Break
          EndIf
          NetData()\Dataset()\DataID = \DataID
          NetData()\Dataset()\Type = \Type
        EndIf
        
        Select \Type
          Case #NetStringArray
            NetData()\Dataset()\Text(\Index) = PeekS(\pData)
            
          Case #NetByteArray
            lbound = \Index
            ubound = \Index + \Count - 1
            ofs = 0
            For index = lbound To ubound
              NetData()\Dataset()\Byte(index) = \pData\bVal[ofs]
              ofs + 1
            Next
            
          Case #NetIntegerArray
            lbound = \Index
            ubound = \Index + \Count - 1
            ofs = 0
            For index = lbound To ubound
              NetData()\Dataset()\Integer(index) = \pData\iVal[ofs]
              ofs + 1
            Next
            
          Case #NetLongArray
            lbound = \Index
            ubound = \Index + \Count - 1
            ofs = 0
            For index = lbound To ubound
              NetData()\Dataset()\Long(index) = \pData\lVal[ofs]
              ofs + 1
            Next
            
          Case #NetFloatArray
            lbound = \Index
            ubound = \Index + \Count - 1
            ofs = 0
            For index = lbound To ubound
              NetData()\Dataset()\Float(index) = \pData\fVal[ofs]
              ofs + 1
            Next
            
          Case #NetDoubleArray
            lbound = \Index
            ubound = \Index + \Count - 1
            ofs = 0
            For index = lbound To ubound
              NetData()\Dataset()\Double(index) = \pData\dVal[ofs]
              ofs + 1
            Next
            
          Case #NetRawData
            lbound = \Index
            ubound = \Index + \Count - 1
            ofs = 0
            For index = lbound To ubound
              NetData()\Dataset()\RawData\bVal[index] = \pData\bVal[ofs]
              ofs + 1
            Next
          
        EndSelect
        ; Check last Datablock
        If \State & 2
          If *NewDataCB
            If *NewDataCB(#PB_NetworkEvent_Data, ConnectionID, @NetData()\Dataset())
              FreeDataset(NetData()\Dataset())
              DeleteMapElement(NetData()\Dataset())
            EndIf
          EndIf
        EndIf
      EndWith
    Until #True
    
    ; On error delete connection and data
    If error
      CloseNetworkConnection(ConnectionID)
      If *NewDataCB
        *NewDataCB(#PB_NetworkEvent_Disconnect, ConnectionID, 0)
      EndIf
      If FindMapElement(NetData(), keyConnectionID)
        ForEach NetData()\Dataset()
          FreeDataset(Netdata()\Dataset())
        Next
        DeleteMapElement(NetData(), keyConnectionID)
      EndIf
    EndIf
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure ThreadServer(*this.udtServerList)
    Protected Event, ConnectionID, keyConnectionID.s
    With *this
      Repeat
        Event = NetworkServerEvent(\ServerID)
        Select Event
          Case #PB_NetworkEvent_Connect
            ; Create NetData
            ConnectionID = EventClient()
            keyConnectionID = Str(ConnectionID)
            If Not FindMapElement(NetData(), keyConnectionID)
              AddMapElement(NetData(), keyConnectionID)
              NetData()\ConnectionID = ConnectionID
              NetData()\DataOffset = 0
              NetData()\Datalen = 0
            EndIf
            Logging("Network: Client connected: ID " + keyConnectionID)
            If \NewDataCB
              \NewDataCB(#PB_NetworkEvent_Connect, ConnectionID, 0)
            EndIf
            
          Case #PB_NetworkEvent_Data
            NetReceiveData(EventClient(),\NewDataCB)
            
          Case #PB_NetworkEvent_Disconnect
            ; Destroy NetData
            ConnectionID = EventClient()
            keyConnectionID = Str(ConnectionID)
            Logging("Network: Client disconnected: ID " + keyConnectionID)
            If \NewDataCB
              \NewDataCB(#PB_NetworkEvent_Disconnect, ConnectionID, 0)
            EndIf
            If FindMapElement(NetData(), keyConnectionID)
              ForEach NetData()\Dataset()
                FreeDataset(Netdata()\Dataset())
              Next
              DeleteMapElement(NetData(), keyConnectionID)
            EndIf
            
          Default
            Delay(10)
            
        EndSelect
        
      Until \ExitServer
      ; Exit Thread
      \ExitServer = 0
    EndWith
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
  Procedure ThreadClient(*this.udtClientList)
    Protected Event, keyConnectionID.s
    
    With *this
      ; Create NetData
      keyConnectionID = Str(\ConnectionID)
      If Not FindMapElement(NetData(), keyConnectionID)
        AddMapElement(NetData(), keyConnectionID)
        NetData()\ConnectionID = \ConnectionID
        NetData()\DataOffset = 0
        NetData()\Datalen = 0
      EndIf
      
      Repeat
        Event = NetworkClientEvent(\ConnectionID)
        Select Event
          Case #PB_NetworkEvent_Data
            NetReceiveData(\ConnectionID, \NewDataCB)
            
          Case #PB_NetworkEvent_Disconnect
            If \NewDataCB
              \NewDataCB(#PB_NetworkEvent_Disconnect, \ConnectionID, 0)
            EndIf
            Break
            
          Default
            Delay(10)
            
        EndSelect
        
      Until \ExitClient
      ; Destroy NetData
      If FindMapElement(NetData(), keyConnectionID)
        ForEach NetData()\Dataset()
          FreeDataset(Netdata()\Dataset())
        Next
        DeleteMapElement(NetData(), keyConnectionID)
      EndIf
      ; Exit Thread
      \ExitClient = 0
    EndWith
    
  EndProcedure
  
  ; -----------------------------------------------------------------------------------
  
EndModule

;- End Module
Zuletzt geändert von mk-soft am 02.07.2016 12:23, insgesamt 18-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modull NetworkArray

Beitrag von mk-soft »

Beispiel Server

Code: Alles auswählen

;-TOP
; NetworkArray Server Example v1.08

Enumeration ;Window
  #Main
EndEnumeration

Enumeration ; Menu
  #Menu
EndEnumeration

Enumeration ; MenuItems
  #MenuExit
EndEnumeration

Enumeration ; Gadgets
  #List
  #Edit
EndEnumeration

Enumeration ; Statusbar
  #Status
EndEnumeration

; Global Variable
Global exit

IncludeFile "Modul_NetworkArray.pb"

; NewData Callback
Procedure NewData(SEvent, ConnectionID, *NewData.NetworkArray::udtDataset)
  
  UseModule NetworkArray

  Protected i, sum_b, sum_i.i, sum_l.l, sum_f.f, sum_d.d
  
  Static Dim result.s(3)
  
  If SEvent = #PB_NetworkEvent_Connect
    NetworkArray::Logging("Callback: Client connected: ID " + Str(ConnectionID))
    ProcedureReturn 0
  ElseIf SEvent = #PB_NetworkEvent_Disconnect
    NetworkArray::Logging("Callback: Client disconnected: ID " + Str(ConnectionID))
    ProcedureReturn 0
  EndIf
  
  With *NewData
    NetworkArray::Logging("Callback: New data from ConnectionID " + Str(ConnectionID) + ": DataID " + Str(\DataID))
    Select \Type
      Case #NetStringArray
        For i = 0 To ArraySize(\Text())
          sum_i + Len(\Text(i))
        Next
        result(1) = "Count of Lines = " + Str(i)
        result(2) = "Count of Charater = " + Str(sum_i)
        
      Case #NetByteArray
        For i = 0 To ArraySize(\Byte())
          sum_b + \Byte(i)
        Next
        result(1) = "Count of Bytes = " + Str(i)
        result(2) = "Byte Result = " + Str(sum_b)
        
      Case #NetIntegerArray
        For i = 0 To ArraySize(\Integer())
          sum_i + \Integer(i)
        Next
        result(1) = "Count of Integer = " + Str(i)
        result(2) = "Integer Result = " + Str(sum_i)
        
      Case #NetLongArray
        For i = 0 To ArraySize(\Long())
          sum_l + \Long(i)
        Next
        result(1) = "Count of Long = " + Str(i)
        result(2) = "Long Result = " + Str(sum_l)
        
      Case #NetFloatArray
        For i = 0 To ArraySize(\Float())
          sum_f + \Float(i)
        Next
        result(1) = "Count of Float = " + Str(i)
        result(2) = "Float Result = " + StrF(sum_f)
        
      Case #NetDoubleArray
        For i = 0 To ArraySize(\Double())
          sum_d + \Double(i)
        Next
        result(1) = "Count of Double = " + Str(i)
        result(2) = "Double Result = " + StrD(sum_d)
        
      Case #NetRawData
        result(1) = "Size of RawData = " + Str(MemorySize(\RawData))
        result(2) = ""
        ;ShowMemoryViewer(\RawData, 2048)
        
    EndSelect
    
    result(0) = "DataID " + Str(\DataID)
    result(3) = "Ready."
    NetworkArray::NetSendStringArray(ConnectionID, \DataID, result())
    
    ProcedureReturn 0
    
    If \Type = #PB_String
      ProcedureReturn 0
    Else
      ProcedureReturn 1
    EndIf
    
  EndWith
  
  UnuseModule NetworkArray

EndProcedure

Procedure UpdateWindow()
  
  Protected x, y, dx, dy, menu, status
  
  menu = MenuHeight()
  If IsStatusBar(#Status)
    status = StatusBarHeight(#Status)
  Else
    status = 0
  EndIf
  x = 0
  y = 0
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - menu - status
  ResizeGadget(#List, x, y, dx, dy)
  
EndProcedure

; Main
Procedure Main()
  
  Protected event, style
  
  style = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
  dx = 640
  dy = 480
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, dx, dy, "Server", style)
    
    ; Enable Fullscreen
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      Protected NewCollectionBehaviour
      NewCollectionBehaviour = CocoaMessage(0, WindowID(#Main), "collectionBehavior") | $80
      CocoaMessage(0, WindowID(#Main), "setCollectionBehavior:", NewCollectionBehaviour)
    CompilerEndIf
    
    ; Menu
    CreateMenu(#Menu, WindowID(#Main))
    MenuTitle("Ablage")
    MenuItem(#MenuExit, "Be&enden")
    ; Gadgets
    ListViewGadget(#List, 0, 0, dx, dy)
    
    ; Statusbar
    CreateStatusBar(#Status, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    
    UpdateWindow()
    
    AddWindowTimer(#Main, 1, 100)
    
    NetworkArray::BindLogging(#PB_Event_FirstCustomValue, #List)
    ServerID = NetworkArray::InitServer(6037, @NewData())
    
    ; Main Loop
    Repeat
      event = WaitWindowEvent(10)
      Select event
        Case #PB_Event_Menu
          Select EventMenu()
              CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                NetworkArray::CloseServer(ServerID)
                exit = #True
                
              CompilerEndIf
              
            Case #MenuExit
              NetworkArray::CloseServer(ServerID)
              exit = #True
              
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #List
              
            Case #Edit
              
          EndSelect
          
        Case #PB_Event_SizeWindow
          Select EventWindow()
            Case #Main
              UpdateWindow()
              
          EndSelect
          
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case #Main
              NetworkArray::CloseServer(ServerID)
              exit = #True
              
          EndSelect
          
      EndSelect
      
    Until exit
    
  EndIf
  
EndProcedure : Main()

End
Beispiel Client

Code: Alles auswählen

;-TOP
; NetworkArray Client Example v1.08

Enumeration ;Window
  #Main
EndEnumeration

Enumeration ; Menu
  #Menu
EndEnumeration

Enumeration ; MenuItems
  #MenuSend1
  #MenuSend2
  #MenuSend3
  #MenuSend4
  #MenuSend5
  #MenuSend6
  #MenuSendAll
  #MenuSendRawData
  #MenuExit
EndEnumeration

Enumeration ; Gadgets
  #List
EndEnumeration

Enumeration ; Statusbar
  #Status
EndEnumeration

Procedure.s Chars(Lenght, Char.s)
  Protected result.s
  result = Space(Lenght)
  ReplaceString(result, " ", Char, #PB_String_InPlace)
  ProcedureReturn result
EndProcedure

; Global Variable
Global exit

;Global Dim text.s(16249) ; Crash on MacOS X64 El Captain
Global Dim text.s(1000)
Global Dim bVal.b(10000)
Global Dim iVal.i(10000)
Global Dim lVal.l(10000)
Global Dim fVal.f(10000)
Global Dim dVal.d(10000)
Global *RawData

For i = 0 To ArraySize(bVal())
  bVal(i) = i % 100
Next
For i = 0 To ArraySize(iVal())
  iVal(i) = 100000 + i
Next
For i = 0 To ArraySize(lVal())
  lVal(i) = 200000 + i
Next
For i = 0 To ArraySize(fVal())
  fVal(i) = 300000.1 + i
Next
For i = 0 To ArraySize(dVal())
  dVal(i) = 400000.2 + i
Next

*RawData = AllocateMemory(100000)
FillMemory(*RawData, MemorySize(*RawData), $A0A0A0A0, #PB_Long)

IncludeFile "Modul_NetworkArray.pb"

; Functions

Procedure NewData(SEvent, ConnectionID, *NewData.NetworkArray::udtDataset)
  
  UseModule NetworkArray

  Protected i
  
  If SEvent = #PB_NetworkEvent_Disconnect
    NetworkArray::Logging("Callback: Server disconnected: ID " + Str(ConnectionID))
    Delay(1000)
    exit = 1
    ProcedureReturn 0
  EndIf
  
  With *NewData
    NetworkArray::Logging("Callback: New data from ConnectionID " + Str(ConnectionID) + ": DataID " + Str(\DataID))
    Select \Type
      Case #NetStringArray
        For i = 0 To ArraySize(\Text())
          NetworkArray::Logging("Callback: Text(" + i + ") = " + \Text(i))
        Next
        
      Case #NetByteArray
        For i = 0 To ArraySize(\Byte())
          Debug "Byte(" + i + ") = " + \Byte(i)
        Next
        
      Case #NetIntegerArray
        For i = 0 To ArraySize(\Integer())
          Debug "Integer(" + i + ") = " + \Integer(i)
        Next
        
      Case #NetLongArray
        For i = 0 To ArraySize(\Long())
          Debug "Long(" + i + ") = " + \Long(i)
        Next
        
      Case #NetFloatArray
        For i = 0 To ArraySize(\Float())
          Debug "Float(" + i + ") = " + \Float(i)
        Next
        
      Case #NetDoubleArray
        For i = 0 To ArraySize(\Double())
          Debug "Double(" + i + ") = " + \Double(i)
        Next
        
      Case #NetRawData
        Debug "RawData"
         
    EndSelect
    
  EndWith
  
  ProcedureReturn 1
  
  UnuseModule NetworkArray

EndProcedure

Procedure UpdateWindow()
  
  Protected x, y, dx, dy, menu, status
  
  menu = MenuHeight()
  If IsStatusBar(#Status)
    status = StatusBarHeight(#Status)
  Else
    status = 0
  EndIf
  x = 0
  y = 0
  dx = WindowWidth(#Main)
  dy = WindowHeight(#Main) - menu - status
  ResizeGadget(#List, x, y, dx, dy)
  
EndProcedure

; Main
Procedure Main()
  
  Protected event, style, ConnectionID, timer
  
  style = #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
  dx = 600
  dy = 400
  
  If OpenWindow(#Main, #PB_Ignore, #PB_Ignore, dx, dy, "Client", style)
    
    ; Enable Fullscreen
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      Protected NewCollectionBehaviour
      NewCollectionBehaviour = CocoaMessage(0, WindowID(#Main), "collectionBehavior") | $80
      CocoaMessage(0, WindowID(#Main), "setCollectionBehavior:", NewCollectionBehaviour)
    CompilerEndIf
    
    ; Menu
    CreateMenu(#Menu, WindowID(#Main))
    MenuTitle("Common")
    MenuItem(#MenuSend1, "Send Text")
    MenuItem(#MenuSend2, "Send Byte")
    MenuItem(#MenuSend3, "Send Integer")
    MenuItem(#MenuSend4, "Send Long")
    MenuItem(#MenuSend5, "Send Float")
    MenuItem(#MenuSend6, "Send Double")
    MenuItem(#MenuSendAll, "Send All")
    MenuBar()
    MenuItem(#MenuSendRawData, "Send RawData")
    MenuBar()
    MenuItem(#MenuExit, "E&xit")
    ; Gadgets
    ListViewGadget(#List, 0, 0, dx, dy)
    
    ; Statusbar
    CreateStatusBar(#Status, WindowID(#Main))
    AddStatusBarField(#PB_Ignore)
    
    UpdateWindow()
    
    NetworkArray::BindLogging(#PB_Event_FirstCustomValue, #List)
    ConnectionID = NetworkArray::InitClient("127.0.0.1", 6037, @NewData())
    ;ConnectionID = NetworkArray::InitClient("192.168.170.20", 6037, @NewData())
    ;ConnectionID = NetworkArray::InitClient("PC040", 6037, @NewData())
    ;ConnectionID = NetworkArray::InitClient("Linux1604", 6037, @NewData())
    If Not ConnectionID
      Debug "Server not Found"
      End
    EndIf
    
    ; Main Loop
    Repeat
      event = WaitWindowEvent(10)
      Select event
        Case #PB_Event_Menu
          Select EventMenu()
              CompilerIf #PB_Compiler_OS = #PB_OS_MacOS   
              Case #PB_Menu_About
                
              Case #PB_Menu_Preferences
                
              Case #PB_Menu_Quit
                NetworkArray::CloseClient(ConnectionID)
                exit = #True
                
              CompilerEndIf
              
            Case #MenuExit
              NetworkArray::CloseClient(ConnectionID)
              exit = #True
              
            Case #MenuSend1
              For i = 0 To ArraySize(text())
                text(i) = "Number " + Str(i) + " " + Chars(Random(1000), "x")
              Next
              NetworkArray::NetSendStringArray(ConnectionID, 101, text())
              
            Case #MenuSend2
              NetworkArray::NetSendByteArray(ConnectionID, 102, bVal())
              
            Case #MenuSend3
              NetworkArray::NetSendIntegerArray(ConnectionID, 103, iVal())
              
            Case #MenuSend4
              NetworkArray::NetSendLongArray(ConnectionID, 104, lVal())
              
            Case #MenuSend5
              NetworkArray::NetSendFloatArray(ConnectionID, 105, fVal())
              
            Case #MenuSend6
              NetworkArray::NetSendDoubleArray(ConnectionID, 106, dVal())
              
            Case #MenuSendAll
              For i = 0 To ArraySize(text())
                text(i) = "Number " + Str(i) + " " + Chars(Random(1000), "x")
              Next
              NetworkArray::NetSendStringArray(ConnectionID, 101, text())
              NetworkArray::NetSendByteArray(ConnectionID, 102, bVal())
              NetworkArray::NetSendIntegerArray(ConnectionID, 103, iVal())
              NetworkArray::NetSendLongArray(ConnectionID, 104, lVal())
              NetworkArray::NetSendFloatArray(ConnectionID, 105, fVal())
              NetworkArray::NetSendDoubleArray(ConnectionID, 106, dVal())
              
            Case #MenuSendRawData
              NetworkArray::NetSendRawData(ConnectionID, 201, *RawData, MemorySize(*RawData))
              
          EndSelect
          
          
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #List
          EndSelect
          
        Case #PB_Event_SizeWindow
          Select EventWindow()
            Case #Main
              UpdateWindow()
          EndSelect
          
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case #Main
              NetworkArray::CloseClient(ConnectionID)
              exit = #True
          EndSelect
          
      EndSelect
      
    Until exit
    
  EndIf
  
EndProcedure : Main()

End
Zuletzt geändert von mk-soft am 26.06.2016 16:51, insgesamt 6-mal geändert.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Modul NetworkArray

Beitrag von STARGÅTE »

Ich habe einige Fagen zu deiner Sendeprozedur:
  • Wieso werden immer 32768 Byte reserviert, wenn doch deine udtDataBlock Struktur gerade mal einige Byte hat (zumindest bei den Fix-Typen)?
  • Sehe ich das Richtig, dass du bei einem Array jedes Feld einzeln mit eigenem eigenen Header sendest?
    Ist das nicht etwas ineffizient, in bezug auf Zeit und Datenvolumen?
  • Außerdem sehe ich da ein Delay(10), wozu ist da da?
Zu NetReceiveData auch noch ein paar Hinweise:
  • Du benutzt dort:

    Code: Alles auswählen

    count = ReceiveNetworkData(ConnectionID, *data + 4, len)
            If count <> len
              Debug "NetworkArray: Error Datalen size"
              Break
            EndIf
    Dieser Abbruch ist zu krittisch! Bei der Übertragung allgemein und vorallem bei Strings oder großen Daten, können die Daten, die mit einem Send gesendet wurden, durchaus mehreren ReceiveNetworkData nötig machen.
    Wenn count < len ist, ist das kein Fehler in der Übertragung, sondern es muss einfach weiter gewartet und weiter empfangen werden. Die Daten also noch nicht freigeben und stattdessen sowas wie: "*data + count" und "len - count"
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul NetworkArray

Beitrag von mk-soft »

Ich habe einige Fagen zu deiner Sendeprozedur:
Wieso werden immer 32768 Byte reserviert, wenn doch deine udtDataBlock Struktur gerade mal einige Byte hat (zumindest bei den Fix-Typen)?
Sehe ich das Richtig, dass du bei einem Array jedes Feld einzeln mit eigenem eigenen Header sendest?
Ist das nicht etwas ineffizient, in bezug auf Zeit und Datenvolumen?
Außerdem sehe ich da ein Delay(10), wozu ist da da?
Ist noch nicht Optimiert. Werde noch mehrere Elemente pro Block übertragen. Da für ist in den Bockdata der Eintrag Count gedacht.
Bei String gibt es später noch eine Limitierung wie lang ein einzelner String sein darf.
Das Delay(10) beim senden kommt später raus.
Zu NetReceiveData auch noch ein paar Hinweise:

Du benutzt dort:
....
Habe so weit festgestellt das die Network-Library in diesen Punkt sauber arbeit.
Erst wenn ein Paket vollständig angekommen ist, wird dieser an das Programm übergeben.
Da mehrere Pakete vorhanden sein kann hole ich diese einzelne vollständige Pakete nacheinander ab.

Zuerst die ersten 8 Byte (Neu ProtocolID und Datalen)
Dann die Daten aus einen Paket. Bei String ist diese länge immer unterschiedlich. Wenn die Optimerung der anderen Werte durch ist auch diese.
Danach steht der interne Zeiger auf dem nächsten Paket, wenn einer vorhanden ist.

Werde noch die maximale große eines Paketes begrenzen.

P.S. An der Paketlänge muss ich noch arbeiten. Ist wohl OS Abhängig. Ist noch Beta...
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul NetworkArray

Beitrag von mk-soft »

@STARGÅTE

Hattest rechts mit der Datenlänge. Problem gelöst :wink:
Es können jetzt String mit bis zu einer länge von 30000 Zeichen versendet werden.
Optimierung von den anderen Arrays fehlt noch.

:allright:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6999
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Modul NetworkArray

Beitrag von STARGÅTE »

Das ein SendNetworkData in mehreren Stückchen bei ReceiveNetworkData ankommt, kann man auch nur beobachten, wenn man eine langsame Verbindung auf der Senderseite hat. Über Local Network sieht man das also weniger als wenn man auf Daten wartet die mit 10 kB/s oder weniger reinplätschern.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul NetworkArray

Beitrag von mk-soft »

Update v1.01

NetSendLongArray hingefügt und das Senden optimiert.
Ausser bei StringArray werden jetzt mehrere Elemente aus einem Array als ein Block gesendet. Die Blockgröße liegt aber immer noch unter 1 kByte.

Sollte jetzt soweit alles gut funktionieren... Bitte wenn möglich testen

FF :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul NetworkArray

Beitrag von mk-soft »

Update v1.03
- Added SetSendByteArray
- Parameter erweitert bei InitServer und InitClient
- Projekt aufgeräumt
- Beispiele überarbeitet

Bitte testen :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul NetworkArray

Beitrag von mk-soft »

Update v1.07
- Optimierung MultiServer und MultiClient

Im lokalen Netzwerk mit 100 Mbit läuft es gut. Als Single-Server, sowie auch als Multi-Server mit 2 Ports. Auch bei sehr grossen Datenmengen (mehr als 20Mbyte Textdaten).
Über das Internet konnte ich es noch nicht testen...

Wenn möglich bitte testen... :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
mk-soft
Beiträge: 3701
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul NetworkArray

Beitrag von mk-soft »

Update v1.08
- Geändert: Eigene Nummern für Datentype
- Geändert: Validieren vom Header
- Hinzugefügt: NetSendRawData(...)
- Update Beispiele

Bitte testen... :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Antworten