I programed a server-application which should provide some cryptographic functions to clients. If I use this code without threads, everything went fine (exept the bad performance). If I use threads, everything is fine until I use two clients. Somethimes the message is lost and sometimes the program even crashes.
Here is the server:
Code: Select all
; Network-Test
; ##############################################
; THREAD ROUTINE
; ##############################################
Procedure ManageConnection(ConnectionID.l)
; Threaded Management. The parameter is the used network-connection-id
Protected length.l, Received.s
Protected *NetworkBuffer.l
Protected tStart.l, tDuration.l, tCount.l
Shared lngMutex.l
; receive data from network connection until the last char is "X" or for max. 5 seconds
Received.s = ""
tCount.l = 0
tStart.l = ElapsedMilliseconds()
Repeat
If tCount.l > 0: Delay(10): EndIf ; to avoid 100% CPU
*NetworkBuffer.l = AllocateMemory(8192) ; 8 KB Puffer for Server
length.l = ReceiveNetworkData(ConnectionID.l, *NetworkBuffer.l, 8192)
If length.l > 0
Received.s = Received.s + PeekS(*NetworkBuffer.l, length.l)
tCount.l = tCount.l + 1
EndIf
FreeMemory(*NetworkBuffer.l)
Until Right(Received.s, 1) = "X" Or ElapsedMilliseconds() > tStart.l + 5000 ; 5 seconds timeout
; close network connection
CloseNetworkConnection(ConnectionID.l)
; do some work for 30ms
tStart.l = ElapsedMilliseconds() + 30
While ElapsedMilliseconds() < tStart.l: Wend
LockMutex(lngMutex.l)
PrintN(FormatDate("%yyyy/%mm/%dd %hh:%ii:%ss", Date()) + " - " + Left(Received.s, 35))
UnlockMutex(lngMutex.l)
EndProcedure
; ##############################################
; MAIN ROUTINE
; ##############################################
InitNetwork()
lngMutex.l = CreateMutex() ; create a mutex to sync output between threads
OpenConsole()
ServerConnectionID.l = CreateNetworkServer(1, 999, #PB_Network_TCP)
PrintN("Server started listening on port 999. Press ESC to stop.")
PrintN(" ")
While Quit.b = #False
; press ESC to close
key_pressed.s = Inkey()
If Left(key_pressed.s, 1) = Chr(27)
Erg.l = MessageRequester("Shutdown Server?","Do you really want to shutdown the server?",#PB_MessageRequester_YesNo + #MB_SYSTEMMODAL)
If Erg.l = #PB_MessageRequester_Yes
Quit.b = #True
EndIf
EndIf
; check network data
SEvent.l = NetworkServerEvent()
If SEvent.l <> 0: CID.l = EventClient(): EndIf
Select SEvent.l
Case 1 ; new Client
Case 2 ; data arrival
; uncomment to avoid threading
; ManageConnection(CID.l)
; uncomment to use threading
CreateThread(@ManageConnection(), CID.l)
Case 4 ; client disconnected
EndSelect
Delay(1) ; avoid 100% CPU
Wend
; cleanup
FreeMutex(lngMutex.l) ; free mutex
CloseNetworkServer(1)
CloseConsole()
End
Code: Select all
; Test-Client
InitNetwork()
For x.l = 1 To 500
ConnectionID.l = OpenNetworkConnection("localhost", 999)
If ConnectionID.l <> 0
SendNetworkString(ConnectionID, "This should get received..." + Space(2000) + "X")
CloseNetworkConnection(ConnectionID.l)
Else
Debug "no connection!"
EndIf
Delay(20)
Next
Now start one client and everything will be ok (needs about 17 seconds here). But if you start the client two times, there will be some curious behaviour (the server will get very slow and sometimes the message get's lost).
The question is: Is it my application or is it the network stack? How can I count the number of running threads?
Do you know any hint for me to let this baby run smooth? Is there a bug inside? Such situations may occur and I need to handle this in a clean way. It is ok, in such situation, that the performance slows down. But not in this way (one per second and less)

Any ideas?
Kukulkan