Module NetworkArray

Share your advanced PureBasic knowledge/code with the community.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Module NetworkArray

Post by mk-soft »

Module for transmitting arrays (Dim) via network.

Receipt of data is carried out in the thread and passed to a callback routine.
The structure of the callback function must have the following structure:
NewDataCB (SEvent, ConnectionID, * NewData.udtDataset)
If the callback function returns non-zero, the received data will be deleted.

For sending the data, there are "NetSendStringArray(...), NetSend...
This can be communicated with to identify a DataID.

A single string in the array must in Unicode contain up to 30,000 characters and ASCII up to 60000 characters.
If the server is running in Unicode, and the client must be running in Unicode.
When using IntegerArray have both (server and client), run as 32bit or 64bit

Update v1.08
- Changed: Own numbers for type of data
- Changed: Validation of header
- Added: NetSendRawData(...)
- Update: Examples

Update v1.091
- Bugfix for the MacOS X64-Version of Purebasic

Modul_NetworkArray.pb

Code: Select all

;-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
Please test it :wink:
Last edited by mk-soft on Sat Jul 02, 2016 11:21 am, edited 9 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Module NetworkArray

Post by mk-soft »

Example Server

Code: Select all

;-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
Example Client

Code: Select all

;-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
Last edited by mk-soft on Sun Jun 26, 2016 2:17 pm, edited 2 times in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Module NetworkArray

Post by mk-soft »

Update v1.03
- Added NetSendByteArray
- Added parameter by InitServer and InitClient
- Update examples
- Cleanup project

Please test it :wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Module NetworkArray

Post by Kwai chang caine »

Hello MkSoft

I have test it on W7 and v5.40 x86 and apparently all are done :D
Server wrote:[2016-06-22 11.13.43] Network: Init Server: ID 27419328
[2016-06-22 11.13.47] Network: Client connected: ID 27419464
[2016-06-22 11.13.47] Callback: Client connected: ID 27419464
[2016-06-22 11.13.49] Callback: New data from ConnectionID 27419464: DataID 101
[2016-06-22 11.13.49] Callback: New data from ConnectionID 27419464: DataID 102
[2016-06-22 11.13.49] Callback: New data from ConnectionID 27419464: DataID 103
[2016-06-22 11.13.49] Callback: New data from ConnectionID 27419464: DataID 104
[2016-06-22 11.13.49] Callback: New data from ConnectionID 27419464: DataID 105
[2016-06-22 11.13.49] Callback: New data from ConnectionID 27419464: DataID 106
Client wrote:[2016-06-22 11.13.47] Network: Init Network Connection: ID 25540736
[2016-06-22 11.13.49] Callback: New data from ConnectionID 25540736: DataID 101
[2016-06-22 11.13.49] Callback: Text(0) = DataID 101
[2016-06-22 11.13.49] Callback: Text(1) = Count of Charater = 513662
[2016-06-22 11.13.49] Callback: Text(2) = Ready.
[2016-06-22 11.13.49] Callback: New data from ConnectionID 25540736: DataID 102
[2016-06-22 11.13.49] Callback: Text(0) = DataID 102
[2016-06-22 11.13.49] Callback: Text(1) = Byte Result = 4950000
[2016-06-22 11.13.49] Callback: Text(2) = Ready.
[2016-06-22 11.13.49] Callback: New data from ConnectionID 25540736: DataID 103
[2016-06-22 11.13.49] Callback: Text(0) = DataID 103
[2016-06-22 11.13.49] Callback: Text(1) = Integer Result = 100600500
[2016-06-22 11.13.49] Callback: Text(2) = Ready.
[2016-06-22 11.13.49] Callback: New data from ConnectionID 25540736: DataID 104
[2016-06-22 11.13.49] Callback: Text(0) = DataID 104
[2016-06-22 11.13.49] Callback: Text(1) = Long Result = 200700500
[2016-06-22 11.13.49] Callback: Text(2) = Ready.
[2016-06-22 11.13.49] Callback: New data from ConnectionID 25540736: DataID 105
[2016-06-22 11.13.49] Callback: Text(0) = DataID 105
[2016-06-22 11.13.49] Callback: Text(1) = Float Result = 5.0050001144
[2016-06-22 11.13.49] Callback: Text(2) = Ready.
[2016-06-22 11.13.49] Callback: New data from ConnectionID 25540736: DataID 106
[2016-06-22 11.13.49] Callback: Text(0) = DataID 106
[2016-06-22 11.13.49] Callback: Text(1) = Double Result = 5.005
[2016-06-22 11.13.49] Callback: Text(2) = Ready.
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Module NetworkArray

Post by mk-soft »

Thanks for testing :wink:

I have a new update to optimized for use as multi-server and multi-client ... :!:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Module NetworkArray

Post by Joris »

mk-soft I would like to test it if I can ...

I just understand a bit of the basics of networking, but yeah... not enough to even know how to test this.
I have only one PC and one labtop which I can both connect on the internet with a Dlan here. So can this setup become used as client and server ?

If you just wont to explain a bit on the basic use of your code, I will test it here too (if able on my setup then, both computers still XP)

Thanks.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Module NetworkArray

Post by Kwai chang caine »

Me i just test on one machine.
Simple, you run the server code, and after the client code
If you need IP, you must use "127.0.0.1" or "localhost" or the IP of your machine if that's not works in this line in the client :wink:

Code: Select all

ConnectionID = NetworkArray::InitClient("127.0.0.1", 6037, @NewData())
ImageThe happiness is a road...
Not a destination
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Module NetworkArray

Post by Joris »

Ok thanks.

I got it running but had to disbale the part
;CompilerError "Use Compileroption Threadsafe!"
I checked that setting but it kept on complaining it wasn't set....
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Module NetworkArray

Post by mk-soft »

You must enable threadsafe on main files server and client, because it´s works asynchrony ...
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Module NetworkArray

Post by mk-soft »

Update v1.08
- Changed: Own numbers for type of data
- Changed: Validation of header
- Added: NetSendRawData(...)
- Update: Examples

Please testing... :wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Joris
Addict
Addict
Posts: 885
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Re: Module NetworkArray

Post by Joris »

Could you put it in a zip file....much easier to (re-)select and copy paste the whole thing.

Thanks
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Module NetworkArray

Post by mk-soft »

Update v1.09
- Bugfix for the MacOS X64-Version of Purebasic (problems with Dim)

:wink:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
error_systeme
New User
New User
Posts: 1
Joined: Tue Apr 02, 2019 7:57 pm

Re: Module NetworkArray

Post by error_systeme »

good day, everything works fine, but there is a problem when I close the client the server also automatically closes. also the situation if I close the server the client also falls off. How to make when you disable the server, the client waited for the connection? and also that the server waited for connection of clients instead of was closed. Thanks. The author of this module is here?
User avatar
mk-soft
Always Here
Always Here
Posts: 5335
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Module NetworkArray

Post by mk-soft »

A client always connects to the server and not to another one.
When the client is properly terminated, the server detects that the client has disconnected. The server does not terminate.
If the server is properly terminated, the server disconnects all client connections. The clients also notice this.

Since in the client example in the procedure NewData(...) the global variable "exit" is set to 1 with disconnect, the client program terminates.

If the server is terminated, the client must try to reestablish the connection until the server is back.

Translated with www.DeepL.com/Translator
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Module NetworkArray

Post by DK_PETER »

That is actually pretty good.
Thanks for sharing. :)
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Post Reply