NicTheQuick,
Once upon a time a man was cleaning his ears and mute the world (In which post You think my English got broken?, may be we both should take English course?)
I am posting my test code which will be then used after all bugs in my code corrected. The code may have incorrect usage of mutex or semaphore as I am not familiar with them very well.
Server.pb
Code: Select all
Global tmpCounter
Global Semaphore = CreateSemaphore()
Global Mutex = CreateMutex()
Import ""
GetThreadId(ThreadHandle.I)
EndImport
Structure TParseData
XPath.s
XMD.s
*XData
EndStructure
Structure TCMDo
*srv.TServer
clID.i
cmdID.i
EndStructure
Structure TCMData
szData.i
pathData.s
*memData
EndStructure
Structure TCMDef
cmdParentID.i
cmdID.i
CMD.s
inData.TCMData
outData.TCMData
CMDState.i
clID.i
EndStructure
Structure TClient
clID.i
IP.s
Port.l
connStat.b
thdID.i
exiThd.b
CMD.TCMDef
EndStructure
Structure TServer
srvID.i
Port.l
Protocol.l
IPv.l
interfaceIP.s
Map Clients.TClient()
EndStructure
#DataBuff = 1024
Declare thdCMDo(*srv.TServer)
Procedure INITsrv(*srv.TServer)
InitNetwork()
UseMD5Fingerprint()
Protected hThread
Protected srvMod, SERVent, ServerID, ClientID
Protected *Buffer0 = AllocateMemory(#DataBuff),
DoneQty, StepQty
If *srv\Port > 0 And *srv\Port < 65000
If *srv\Protocol = #PB_Network_TCP Or *srv\Protocol = #PB_Network_UDP
If *srv\IPv = #PB_Network_IPv4 Or *srv\IPv = #PB_Network_IPv6
srvMod = *srv\Protocol | *srv\IPv
Else
srvMod = *srv\Protocol
EndIf
Else
srvMod = #PB_Network_TCP | #PB_Network_IPv4
EndIf
If *srv\interfaceIP = ""
*srv\srvID = CreateNetworkServer(#PB_Any, *srv\Port, srvMod)
Else
*srv\srvID = CreateNetworkServer(#PB_Any, *srv\Port, srvMod, *srv\interfaceIP)
EndIf
Repeat
SERVent = NetworkServerEvent()
Select SERVent
Case #PB_NetworkEvent_None
Delay(10)
Case #PB_NetworkEvent_Connect ;- #PB_NetworkEvent_Connect
ServerID = EventServer()
ClientID = EventClient()
LockMutex(Mutex)
*srv\Clients(Str(ClientID))\clID = ClientID
*srv\Clients(Str(ClientID))\IP = IPString(GetClientIP(ClientID), #PB_Network_IPv4)
*srv\Clients(Str(ClientID))\Port = GetClientPort(ClientID)
*srv\Clients(Str(ClientID))\CMD\clID = ClientID
*srv\Clients(Str(ClientID))\CMD\inData\memData = AllocateMemory(#DataBuff)
*srv\Clients(Str(ClientID))\CMD\outData\memData = AllocateMemory(#DataBuff)
*srv\Clients(Str(ClientID))\connStat = #True
UnlockMutex(Mutex)
Case #PB_NetworkEvent_Disconnect ;- #PB_NetworkEvent_Disconnect
ServerID = EventServer()
ClientID = EventClient()
LockMutex(Mutex)
*srv\Clients(Str(ClientID))\connStat = #False
UnlockMutex(Mutex)
;{ TestPurpose
; If FindMapElement(*srv\Clients(), Str(ClientID))
; FreeMemory(*srv\Clients(Str(ClientID))\CMD\inData\memData)
; FreeMemory(*srv\Clients(Str(ClientID))\CMD\outData\memData)
; DeleteMapElement(*srv\Clients(), Str(ClientID))
; EndIf
;
; If FindMapElement(*srv\Clients(), Str(ClientID))
; Debug "Found but shouldnt: " + *srv\Clients(Str(ClientID))\clID
; Else
; Debug "DeleteMapOK"
; EndIf
;
; If MapSize(*srv\Clients()) = 0
; Debug "OK"
; EndIf
;}
Case #PB_NetworkEvent_Data ;- #PB_NetworkEvent_Data
ServerID = EventServer()
ClientID = EventClient()
If FindMapElement(*srv\Clients(), Str(ClientID))
DoneQty = 0
StepQty = 0
Repeat
Qty = ReceiveNetworkData(ClientID, *Buffer0, #DataBuff) ; take the coins
If Qty > 0
DoneQty + Qty
LockMutex(Mutex)
If DoneQty >= MemorySize(*srv\Clients(Str(ClientID))\CMD\inData\memData) ; bank is not empty ?
*srv\Clients(Str(ClientID))\CMD\inData\memData = ReAllocateMemory(*srv\Clients(Str(ClientID))\CMD\inData\memData, MemorySize(*srv\Clients(Str(ClientID))\CMD\inData\memData) + #DataBuff)
EndIf
CopyMemory(*Buffer0, *srv\Clients(Str(ClientID))\CMD\inData\memData + StepQty, Qty)
UnlockMutex(Mutex)
StepQty + Qty
EndIf
Until Qty <= 0 ; quit if bank is empty
*srv\Clients(Str(ClientID))\CMD\inData\szData = DoneQty
FillMemory(*Buffer0, #DataBuff, 0, #PB_Byte)
hThread = CreateThread(@thdCMDo(), *srv)
LockMutex(Mutex)
*srv\Clients(Str(ClientID))\thdID = GetThreadID(ThreadID(hThread))
UnlockMutex(Mutex)
; Debug "Internal thdID: " + *srv\Clients(Str(ClientID))\thdID
EndIf
EndSelect
ForEver
ProcedureReturn #True
EndIf
ProcedureReturn #False
EndProcedure
Procedure thdCMDo(*srv.TServer)
Protected thdID = GetCurrentThreadId_()
Protected clID
Protected CounterTMP = tmpCounter
Protected *cpSrv.TServer = AllocateMemory(SizeOf(TServer));AllocateStructure(TServer)
InitializeStructure(*cpSrv, TServer)
Delay(1000)
LockMutex(Mutex)
CopyStructure(*srv, *cpSrv, TServer)
UnlockMutex(Mutex)
Delay(1000)
Repeat
ForEach *cpSrv\Clients()
If MapKey(*cpSrv\Clients()) <> ""
If thdID = *cpSrv\Clients()\thdID
clID = *cpSrv\Clients()\clID
tmpCounter + 1
Debug Str(tmpCounter) + " Found for client: " + clID
Debug "Data for Client: " + Str(clID) + " | " + PeekS(*cpSrv\Clients(Str(clID))\CMD\inData\memData, *cpSrv\Clients(Str(clID))\CMD\inData\szData, #PB_Unicode) + "|"
Break 2
EndIf
EndIf
Next
Until tmpCounter <> CounterTMP
Debug "Last found element for client: " + Str(*cpSrv\Clients(Str(clID))\clID) + " is: " + tmpCounter
ClearStructure(*cpSrv, TServer)
Debug "chkIfClear Interface: " + *cpSrv\interfaceIP
; FreeStructure(*cpSrv.TServer)
EndProcedure
Define *srv.TServer = AllocateMemory(SizeOf(TServer));AllocateStructure(TServer)
InitializeStructure(*srv, TServer)
*srv\Port = 8888
*srv\Protocol = #PB_Network_TCP
*srv\interfaceIP = "127.0.0.1"
Define MainTHD = CreateThread(@INITsrv(), *srv)
Repeat
Delay(10)
ForEver
Client.pb
Code: Select all
Procedure Cli()
If InitNetwork() = 0
MessageRequester("Error", "Can't initialize the network !", 0)
End
EndIf
#String = "TEST"
*String = AllocateMemory(StringByteLength("TEST", #PB_Unicode)+2)
PokeS(*String, #String, StringByteLength("TEST", #PB_Unicode), #PB_Unicode)
UseMD5Fingerprint()
Debug Fingerprint(*String, StringByteLength("TEST", #PB_Unicode), #PB_Cipher_MD5)
#cliPort = 8888;6832
#ConSize = 10000
Dim Connexn(#ConSize)
Debug "Connecting"
For i = 1 To #ConSize
Connexn(i) = OpenNetworkConnection("127.0.0.1", #cliPort, #PB_Network_TCP)
Next
Debug "SendDataFull"
For i = 1 To #ConSize
If Connexn(i) And ConnectionID(Connexn(i))
SendNetworkData(Connexn(i), *String, StringByteLength("TEST", #PB_Unicode))
EndIf
Next
Debug "SendDataShort"
For i = 1 To 10
If Connexn(i) And ConnectionID(Connexn(i))
SendNetworkData(Connexn(i), *String, StringByteLength("TEST", #PB_Unicode))
EndIf
Next
Debug "Disconnect"
For i = 1 To #ConSize
If Connexn(i) And ConnectionID(Connexn(i))
CloseNetworkConnection(Connexn(i))
EndIf
Next
EndProcedure
Cli()
little bit shortened