Is network funtion threadsafed

Just starting out? Need help? Post your questions and find answers here.
User avatar
mk-soft
Always Here
Always Here
Posts: 6404
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Is network funtion threadsafed

Post by mk-soft »

Hello Fred

The network function thread-safe if the server is running in the first thead and the client run in the second thead?

A test with telnet to the server looks good.

Example

Code: Select all

;- Konstanten
Enumeration ; Window ID
  #Window
EndEnumeration

Enumeration ; Menu ID
  #Menu
EndEnumeration

Enumeration ; MenuItem ID
  #Menu_Exit
EndEnumeration

Enumeration ; Statusbar ID
  #Statusbar
EndEnumeration

Enumeration ; Gadget ID
  #List
EndEnumeration

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

; Es müssen immer alle Variablen declariert werden

EnableExplicit

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

Procedure UpdateWindow()

  Protected x,y,dx,dy
  Protected mn,st,tb
  
  x = 0
  y = 0
  mn = MenuHeight()
  st = StatusBarHeight(#StatusBar)
  ;tb = ToolBarHeight(#ToolBar)
  dx = WindowWidth(#Window)
  dy = WindowHeight(#Window) - mn - st - tb
  ResizeGadget(#List, x, y, dx, dy)
  
EndProcedure

Procedure MyWriteLog(Info.s)
  Protected temp.s
  temp = FormatDate("%YYYY.%MM.%DD %HH:%II:%SS - ", Date()) + Info
  AddGadgetItem(#List, -1, temp)
  If CountGadgetItems(#List) > 500
    RemoveGadgetItem(#List, 0)
  EndIf
  SetGadgetState(#List, CountGadgetItems(#List) - 1)
  SetGadgetState(#List, -1)
EndProcedure

Global MutexLog.i
MutexLog = CreateMutex()

Macro WriteLog(Info)
  LockMutex(MutexLog) : MyWriteLog(Info) : UnlockMutex(MutexLog)
EndMacro

;- Globale Variablen
Global exit = 0

; Server

Procedure thServer(id)
  
  If InitNetwork() = 0
    WriteLog("Server Error: Can't initialize the network !")
    ProcedureReturn 0
  EndIf
  
  Protected Port = 6832
  Protected *Buffer = AllocateMemory(1000)
  Protected SEvent, ClientID, len, text1.s, text2.s, pos
  
  If CreateNetworkServer(0, Port)
  
    WriteLog("Server: Server created (Port "+Str(Port)+").")
    
    Repeat
        
      SEvent = NetworkServerEvent()
    
      Select SEvent
      
        Case #PB_NetworkEvent_Connect
          WriteLog("Server: A new client has connected !")
  
        Case #PB_NetworkEvent_Data
          ClientID = EventClient()
          WriteLog("Server: Client "+Str(ClientID)+" has send a packet !")
          len = ReceiveNetworkData(ClientID, *Buffer, 1000)
          text1 = text1 + PeekS(*Buffer, len)
          pos = FindString(text1, #LF$)
          If pos
            text2 = Left(text1, pos -1)
            text1 = Mid(text1, pos + 1)
            WriteLog("Server: String: "+text2)
          EndIf
  
        Case #PB_NetworkEvent_Disconnect
          WriteLog("Server: Client "+Str(ClientID)+" has closed the connection...")
          
        Case #PB_NetworkEvent_None
          Delay(20)
          
      EndSelect
      
    Until Exit = 1 
    
    WriteLog("Server: Shutdown...")
    
    CloseNetworkServer(0)
  Else
    WriteLog("Server Error: Can't create the server (port in use ?).")
  EndIf

  
EndProcedure

; Client

Procedure thClient(id)
  
  If InitNetwork() = 0
    WriteLog("Client Error: Can't initialize the network !")
    ProcedureReturn 0
  EndIf
  
  Protected Port = 6832
  Protected ConnectionID
  Protected text.s
  
  Repeat
    ; No Connections
    ConnectionID = OpenNetworkConnection("192.168.1.20", Port, #PB_Network_TCP, 5000)
    ;ConnectionID = OpenNetworkConnection("127.0.0.1", Port, #PB_Network_TCP, 5000)
    If ConnectionID
      WriteLog("Client: Client connected To server...")
      
      Repeat
        text = InputRequester("Text to send", "", "")
        If Len(text)
          text + #LF$
          SendNetworkString(ConnectionID, text)
        Else
          CloseNetworkConnection(ConnectionID)
          Break 2
        EndIf
      ForEver
    Else
      WriteLog("Client Error: Can't find the server (Is it launched ?).")
      Delay(100)
    EndIf
  Until exit
  
EndProcedure

; Main in eine Procedure gekapselt

Procedure Main()

  Protected style, event, window, menu, gadget, type
  Protected hServer, hClient
  
  ;- Fenster
  style = #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget
  If OpenWindow(#Window, #PB_Ignore, #PB_Ignore, 400, 300, "Fenster", style)
    ; Menu
    If CreateMenu(#Menu, WindowID(#Window))
      MenuTitle("&Datei")
        MenuItem(#Menu_Exit, "Be&enden")
    EndIf
    ; Statusbar
    CreateStatusBar(#Statusbar, WindowID(#Window))
    ; Gadgets
    ListViewGadget(#List, 0,0,0,0)
    
    ; Init
    WriteLog("Programm gestartet")
    
    hServer = CreateThread(@thServer(), 0)
    hClient = CreateThread(@thClient(), 0)
    
    ;-- Hauptschleife
    Repeat
      event = WaitWindowEvent()
      Select event
        Case #PB_Event_Menu                       ; ein Menü wurde ausgewählt
          menu = EventMenu()
          Select menu
            Case #Menu_Exit
              Exit = 1
          EndSelect
        Case #PB_Event_Gadget                     ; ein Gadget wurde gedrückt
          gadget = EventGadget()
          type = EventType()
        
        Case #PB_Event_CloseWindow                ; das Schließgadget vom Fenster wurde gedrückt
          window = EventWindow()
          If window = #Window
            Exit = 1
          EndIf
         
        Case #PB_Event_Repaint                    ; der Fensterinhalt wurde zerstört und muss neu gezeichnet werden (nützlich für 2D Grafik-Operationen)
        Case #PB_Event_SizeWindow                 ; das Fenster wurde in der Größe verändert
          window = EventWindow()
          If window = #Window
            UpdateWindow()
          EndIf

        Case #PB_Event_MoveWindow                 ; das Fenster wurde verschoben
        Case #PB_Event_ActivateWindow             ; das Fenster wurde aktiviert (hat den Fokus erhalten)
        Case #PB_Event_SysTray                    ; das SysTray wurde aktiviert
     
      EndSelect
     
    Until Exit
  EndIf
  
  While IsThread(hServer)
    While WindowEvent() : Wend
  Wend
  
  While IsThread(hClient)
    While WindowEvent() : Wend
  Wend
  
  Delay(1000)
  
EndProcedure : Main() 
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: 6404
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Is network funtion threadsafed

Post by mk-soft »

The server function I have been moved into a dll
I think it will run without problems.
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
RichAlgeni
Addict
Addict
Posts: 935
Joined: Wed Sep 22, 2010 1:50 am
Location: Bradenton, FL

Re: Is network funtion threadsafed

Post by RichAlgeni »

Network functions are inherently thread safe, as long as the text variables you use are not shared.
PMV
Enthusiast
Enthusiast
Posts: 727
Joined: Sat Feb 24, 2007 3:15 pm
Location: Germany

Re: Is network funtion threadsafed

Post by PMV »

This information is old as PB4.30, but as i don't remember any changes there:
As long as you have just one server in your program running, everything is fine.

:arrow: http://www.purebasic.fr/english/viewtopic.php?t=31803
freak wrote:1) Most of the Network lib is threadsafe even without turning that switch on.

Specifically it is only the creating/closing of network servers and the network
server event handling that should be protected against multiple thread access.
Of course you shouldn't receive/send data for a single client from two threads at
once, but that sounds logical.
MFG PMV
User avatar
mk-soft
Always Here
Always Here
Posts: 6404
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Is network funtion threadsafed

Post by mk-soft »

The server functions and functions of the client must always run independently. Most thread-safe so not enough. Thus the server will outsource functions in a dll.

Thanks to all

: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
Post Reply