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()


