If you outsource the sending of data to another thread and the connection to the partner fails, SendNetworkData crashed.
With Windows and Linux, SendNetworkData returns a result of less than zero and can be aborted.
Server
Code: Select all
;-TOP
CompilerIf #PB_Compiler_Thread = 0
CompilerError "Use Compiler Option ThreadSafe!"
CompilerEndIf
InitNetwork()
Enumeration Windows
#Main
EndEnumeration
Global ExitApplication
Global MutexServer = CreateMutex()
Procedure thServer(id)
Protected ServerID, Event, ConnectionID, cnt
Protected *buffer = AllocateMemory($FFFF)
ServerID = CreateNetworkServer(#PB_Any, 6037)
If ServerID = 0
Debug "Error: Create NetworkServer!"
ProcedureReturn 0
Else
Debug "Create NetworkServer"
EndIf
Repeat
LockMutex(MutexServer)
Event = NetworkServerEvent(ServerID)
ConnectionID = EventClient()
UnlockMutex(MutexServer)
Select Event
Case #PB_NetworkEvent_Connect
Debug "Client Conneceted ID " + ConnectionID
Case #PB_NetworkEvent_Data
cnt = ReceiveNetworkData(ConnectionID, *buffer, $FFFF)
Debug "Receive Data ID " + ConnectionID + " / Len " + cnt
Case #PB_NetworkEvent_Disconnect
Debug "Client Disconneceted ID " + ConnectionID
Default
Delay(10)
EndSelect
Until ExitApplication
Debug "Close NetworkServer"
CloseNetworkServer(ServerID)
Debug "Exit Thread"
EndProcedure
Procedure Main()
Protected thServer
If OpenWindow(#Main, 80, 80, 200, 60, "Server" , #PB_Window_SystemMenu)
thServer = CreateThread(@thServer(), 0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
ExitApplication = #True
If WaitThread(thServer, 1000) = 0
KillThread(thServer)
EndIf
Break
EndSelect
ForEver
EndIf
EndProcedure : Main()
Client
Code: Select all
;-TOP
CompilerIf #PB_Compiler_Thread = 0
CompilerError "Use Compiler Option ThreadSafe!"
CompilerEndIf
InitNetwork()
Enumeration Windows
#Main
EndEnumeration
Enumeration Gadgets
EndEnumeration
Enumeration Status
#MainStatusBar
EndEnumeration
Global ExitApplication, ExitSendData
Global ConnectionID
Procedure thClient(id)
Protected Event, cnt
Protected *buffer = AllocateMemory($FFFF)
ConnectionID = OpenNetworkConnection("127.0.0.1", 6037)
If ConnectionID = 0
Debug "Error: Create NetworkClient!"
ProcedureReturn 0
Else
Debug "Create NetworkClient"
EndIf
Repeat
Event = NetworkClientEvent(ConnectionID)
Select Event
Case #PB_NetworkEvent_Data
cnt = ReceiveNetworkData(ConnectionID, *buffer, $FFFF)
Debug "Receive Data ID " + ConnectionID + " / Len " + cnt
Case #PB_NetworkEvent_Disconnect
Debug "Server Disconneceted"
ExitSendData = #True
Break
Default
Delay(100)
EndSelect
Until ExitApplication
Debug "Close NetworkClient"
CloseNetworkConnection(ConnectionID)
ConnectionID = 0
Debug "Exit Thread Client"
EndProcedure
Procedure thSendData(ConnectionID)
Protected cnt
Repeat
cnt = SendNetworkData(ConnectionID, @"Hello World!", 12)
Debug "Send " + cnt
If cnt < 0
Debug "Send Error"
Break
EndIf
Delay(40)
Until ExitApplication ; Or ExitSendData
Debug "Exit Thread SendData"
EndProcedure
Procedure Main()
Protected thClient, thSend
If OpenWindow(#Main, 80, 180, 200, 60, "Client" , #PB_Window_SystemMenu)
ButtonGadget(0, 10, 10, 180, 30, "Start Send")
thClient = CreateThread(@thClient(), 0)
Repeat
Select WaitWindowEvent()
Case #PB_Event_CloseWindow
ExitApplication = #True
If thClient
If WaitThread(thClient, 1000) = 0
KillThread(thClient)
EndIf
EndIf
If thSend
If WaitThread(thSend, 1000) = 0
KillThread(thSend)
EndIf
EndIf
Break
Case #PB_Event_Gadget
Select EventGadget()
Case 0
If ConnectionID And Not IsThread(thSend)
thSend = CreateThread(@thSendData(), ConnectionID)
EndIf
EndSelect
EndSelect
ForEver
EndIf
EndProcedure : Main()
Current solution:
Check the client port before sending the data.
Code: Select all
; ***************************************************************************************
; Bugfix MacOS SendNetworkData over Threads. mk-soft, 27.10.2019, Version 1.01
; Update 07.05.2020 Version 1.02
CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
Import ""
CFSocketIsValid(Socket) ; -> Boolean
EndImport
Procedure FixSendNetworkData(ClientID, MemoryBufer, Length)
If CFSocketIsValid(ClientID)
ProcedureReturn SendNetworkData(ClientID, MemoryBufer, Length)
Else
ProcedureReturn -2
EndIf
EndProcedure
Macro SendNetworkData(ClientID, MemoryBufer, Length)
FixSendNetworkData(ClientID, MemoryBufer, Length)
EndMacro
CompilerEndIf
; ***************************************************************************************