Ok j'ai retrouvé le code.
Je suis désolé, j'ai dû prendre une ancienne version d'un projet et le code n'est pas du tout fini. Je mettrai trop de temps à modifier la version complète. J'espère que ça pourra te donner des idées.
Code : Tout sélectionner
; -------------------------------------------
;- Module Peer2Peer
; -------------------------------------------
; Interfaces
Enumeration
#Window_9
#Frame3D_20
#Frame3D_21
#Frame3D_23
#Tree_0
#Text_151
#String_98
#Text_152
#Button_47
#Panel_2
#Panel_3
#String_100
#Button_48
#Listview_1
#String_101
#Panel_4
#Text_154
#username
#Text_155
#String_104
#Listview_2
#ListIcon_9
#Text_156
#Text_157
#Text_159
#String_105
#String_106
#String_107
#Text_161
#Text_162
#String_109
#String_111
EndEnumeration
Procedure Open_Window_9()
If OpenWindow(#Window_9 , 221, 181, 992, 671, "Réseau Peer 2 Peer", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar )
If CreateGadgetList(WindowID(#Window_9 ))
Frame3DGadget(#Frame3D_20, 5, 5, 195, 330, "Clients connectés")
Frame3DGadget(#Frame3D_21, 5, 465, 195, 200, "Etat du réseau")
Frame3DGadget(#Frame3D_23, 5, 345, 195, 110, "Amorçage")
TreeGadget(#Tree_0, 15, 25, 175, 300)
TextGadget(#Text_151, 15, 370, 25, 15, "IP")
StringGadget(#String_98, 50, 390, 45, 20, "")
TextGadget(#Text_152, 15, 395, 25, 15, "Port")
ButtonGadget(#Button_47, 55, 425, 90, 20, "Connecter")
StringGadget(#String_100, 210, 645, 770, 20, "")
ButtonGadget(#Button_48, 15, 490, 170, 20, "Démarrer le serveur")
ListViewGadget(#Listview_1, 15, 515, 170, 140)
StringGadget(#String_101, 50, 365, 135, 20, "")
;- Panel15
PanelGadget(#Panel_2, 210, 10, 775, 410)
AddGadgetItem(#Panel_2, -1, "Options")
;- Panel22
PanelGadget(#Panel_4, 8, 8, 755, 370)
AddGadgetItem(#Panel_4, -1, "Général")
TextGadget(#Text_154, 13, 13, 95, 15, "Nom d'utilisateur :")
StringGadget(#username, 113, 8, 130, 20, "TT Défaut !")
AddGadgetItem(#Panel_4, -1, "Serveur")
TextGadget(#Text_155, 18, 13, 75, 20, "Port d'écoute :")
StringGadget(#String_104, 108, 8, 55, 20, "1539")
CloseGadgetList()
AddGadgetItem(#Panel_2, -1, "Logs")
ListViewGadget(#Listview_2, 8, 8, 755, 370)
CloseGadgetList()
;- Panel20
PanelGadget(#Panel_3, 210, 430, 775, 210)
AddGadgetItem(#Panel_3, -1, "Salle commune")
CloseGadgetList()
EndIf
EndIf
EndProcedure
Structure CLIENT
id.l
ip.l
port.l
nom.s
last_action.l
last_action_date.l
ping_sent.b
EndStructure
Global NewList Client.CLIENT()
Structure THREADPARAMETERS
client_ip.l
client_port.l
requete_type.b
connect_ip.s
param1.s
param2.l
EndStructure
Global Serveur.l = 0
Global Network.l = 0
#Port = 1539
Global Port.l = #Port
Global Network_Password.s = "pass"
#TimeOutPing = 10 ; Durée en secondes après laquelle un client est ping-é (on lui envoi un ping, il renvoi un pong)
#TimeOut = 20 ; Durée en secondes après laquelle un client est considéré inactif et sorti de la liste des clients (il n'a pas répondu à un ping)
; Type de Network Packet
Enumeration 1
#Connect
#Disconnect
#Clients
#Message
#File
#Ping
#Pong
#Name
#Network_Password
#None
#Commun_Attaque
#Add_Village
EndEnumeration
;-
; -------------------------------------------------------------------------------------------------
;- === procedure RESEAU & SYSTEM =====
; -------------------------------------------------------------------------------------------------
;------------------- Semaphore Functions ------------------------
Macro Sem_Create(Init, Max)
CreateSemaphore_(#Null, Init, Max, #Null)
EndMacro
Macro Sem_Acquire(Sem)
WaitForSingleObject_(Sem, #INFINITE)
EndMacro
Macro Sem_ReleaseSeveral(Sem, nb)
ReleaseSemaphore_(Sem, nb, #Null)
EndMacro
Macro Sem_Release(Sem)
ReleaseSemaphore_(Sem, 1, #Null)
EndMacro
;---------------- End of Semaphore Functions ---------------------
Global AccessThreadParameters = Sem_Create(1, 1) ; Créer une sémaphore
Procedure GetNetworkPacketType(*buffer)
ProcedureReturn PeekL(*buffer)
EndProcedure
; Identifiant unique d'un client
; Ce système garanti l'unicité de numéro donné aux clients.
Global UNIQUE_CLIENT_IDENTIFIANT.l = 1
Procedure.l GetUCI()
ret.l = UNIQUE_CLIENT_IDENTIFIANT
UNIQUE_CLIENT_IDENTIFIANT + 1
ProcedureReturn ret
EndProcedure
; --------------------------------------------------------------------
;- Gestion du serveur
; --------------------------------------------------------------------
; Ajoute un client dans la liste des clients connus
Procedure AddClient(clientID.l, clientIP.l, clientPort.l, nom.s, date.l, last_action.l = #Connect)
; Vérifie qu'il n'existe pas
client_existe.b = #False
ForEach Client()
If Client()\ip = clientIP And Client()\port = clientPort
client_existe = #True
Break
EndIf
Next
If client_existe = #False
AddElement(Client())
Client()\id = GetUCI()
Client()\ip = clientIP
Client()\port = clientPort
Client()\nom = nom
Client()\last_action = last_action
Client()\last_action_date = date
Else
; Le client existe déjà, on ne fait rien ;)
EndIf
EndProcedure
; Modifie un client connu
Procedure ModifClient(clientID.l, clientIP.l, clientPort.l, nom.s, date.l, last_action.l)
; Vérifie qu'il n'existe pas
client_existe.b = #False
ForEach Client()
If Client()\ip = clientIP And Client()\port = clientPort
client_existe = #True
Break
EndIf
Next
If client_existe = #True
; Modifie le nom
Client()\nom = nom
Client()\last_action = last_action
Client()\last_action_date = date
Else
; Le client existe déjà, on ne fait rien ;)
EndIf
EndProcedure
; Suprime un client de la liste des clients connus
Procedure RemoveClient(clientIP.l, clientPort.l)
client_existe.b = #False
ForEach Client()
If Client()\ip = clientIP And Client()\port = clientPort
client_existe = #True
Break
EndIf
Next
If client_existe
; Le client existe, la liste chainée le référence : on supprime !
DeleteElement(Client())
EndIf
EndProcedure
; Modifie la dernière action du client.
; Utile pour savoir qu'un client est toujours UP
Procedure ClientLastAction(clientID, clientIP, clientPort, last_action, date)
client_existe.b = #False
ForEach Client()
If Client()\ip = clientIP And Client()\port = clientPort
client_existe = #True
Break
EndIf
Next
If client_existe
Client()\last_action = last_action
Client()\last_action_date = date
Client()\ping_sent = 0 ; Autorise de nouveau le ping
EndIf
EndProcedure
; Ajoute l'entête d'un packet de données
Procedure.l AddPacketHeader(*buffer, header.l)
PokeL(*buffer, header)
ProcedureReturn *buffer
EndProcedure
; Procédure permettant d'envoyer à un client, un packet déjà créé
Procedure.b SendPacket(hote.s, port.l, packet.l, length.l)
conn = OpenNetworkConnection(hote, port, #PB_Network_UDP)
ret.b = #False
If conn
SendNetworkData(conn, packet, length)
CloseNetworkConnection(conn)
ret = #True
EndIf
ProcedureReturn ret
EndProcedure
; Procédure permettant de créer une requête.
; Elle doit être lancée dans un thread et synchronisée avec une sémaphore
Procedure CreateRequete(Param.l)
Global AccessThreadParameters
Global Port
*LocalParameters.THREADPARAMETERS = Param
; TRaitement : création de la requête en fonction des parametres
Debug "THREAD Client : "
Debug IPString(*LocalParameters\client_ip) + " : " + Str(*LocalParameters\client_port)
; Libère la variable pour l"affectation
;UnlockMutex(AccessThreadParameters)
; Dans le cas d'une requete de type CLIENTS on libère la mémoire plus tard
If *LocalParameters\requete_type <> #Clients
Sem_Release(AccessThreadParameters)
EndIf
; En fonction du type de requête, fais des actions différentes
; Partie commune, l'envoi du packet est factorisé
length.l = 0
*packet = 0
; Création du packet
Select *LocalParameters\requete_type
Case #Ping
; Envoi un PING
*ping_packet = AllocateMemory(64)
*ping_packet = AddPacketHeader(*ping_packet, #Ping)
PokeL(*ping_packet + 4, Port)
*packet = *ping_packet
length = 8
Case #Pong
; Envoi un PONG
*pong_packet = AllocateMemory(64)
*pong_packet = AddPacketHeader(*pong_packet, #Pong)
PokeL(*pong_packet + 4, Port)
*packet = *pong_packet
length = 8
Case #Connect
; Création du packet de données
*connect_packet = AllocateMemory(9128)
; #Connect
; Format : CONNECT|REMOTE_SERVER_PORT(long)|NAME(str)|PASSWORD(str)
*connect_packet = AddPacketHeader(*connect_packet, #Connect)
PokeL(*connect_packet + 4, Port)
nom.s = *LocalParameters\param1
PokeL(*connect_packet + 8, Len(nom))
PokeS(*connect_packet + 12, nom, Len(nom))
*packet = *connect_packet
length = 12 + Len(nom)
Case #Clients
; #Clients
; Format CLIENTS|REMOTE_SERVER_PORT(long)|NB_CLIENTS(long)|IP(long)|PORT(long)|NAME(str)|[...]
; Copie en local la liste des clients é envoyer et libère la mémoire.
NewList Clt.CLIENT()
*Clt = @*LocalParameters\param2
Sem_Release(AccessThreadParameters)
; Création du packet de données
*client_packet = AllocateMemory(9128)
*client_packet = AddPacketHeader(*client_packet, #Clients)
PokeL(*client_packet + 4, Port)
; Nombre de clients
PokeL(*client_packet + 8, CountList(Clt()))
FirstElement(Clt())
nb_clt.l = 0
delta_clt.l = 0
While nb_clt < CountList(Clt())
PokeL(*client_packet + 12 + delta_clt , Clt()\ip)
PokeL(*client_packet + 16 + delta_clt , Clt()\port)
PokeL(*client_packet + 20 + delta_clt , Len(Clt()\nom))
PokeS(*client_packet + 24 + delta_clt , Clt()\nom, Len(Clt()\nom))
delta_clt + 13
delta_clt + Len(Clt()\nom)
nb_clt + 1
NextElement(Clt())
Wend
; Informations sur le packet
*packet = *client_packet
length = 12 + delta_clt
Case #Name
; Création du packet de données
*name_packet = AllocateMemory(512)
; #Name
; Format : NAME|REMOTE_SERVER_PORT(long)|NOM(str)
*name_packet = AddPacketHeader(*name_packet, #Name)
PokeL(*name_packet + 4, Port)
nom.s = *LocalParameters\param1
PokeL(*name_packet + 8, Len(nom))
PokeS(*name_packet + 12, nom, Len(nom))
; Informations sur le packet
*packet = *name_packet
length = 12 + Len(nom)
EndSelect
; Envoi du packet
If *LocalParameters\client_ip = 0 And *LocalParameters\connect_ip <> ""
conn = OpenNetworkConnection(*LocalParameters\connect_ip, *LocalParameters\client_port, #PB_Network_UDP)
If conn
SendNetworkData(conn, *packet, length)
CloseNetworkConnection(conn)
Debug "Packet envoyé"
EndIf
Else
conn = OpenNetworkConnection(IPString(*LocalParameters\client_ip), *LocalParameters\client_port, #PB_Network_UDP)
If conn
SendNetworkData(conn, *packet, length)
CloseNetworkConnection(conn)
Debug "Packet envoyé"
EndIf
EndIf
EndProcedure
; Ecrit des données dans le log
Procedure Logs(msg.s)
imsg.s = FormatDate("%dd/%mm/%yy - %hh:%ii:%ss", Date()) + " " + msg
AddGadgetItem(#Listview_2, -1, imsg)
EndProcedure
; -------------------------------------------------------------------------------------------------
;- ===== Procedure INTERFACE =====
; -------------------------------------------------------------------------------------------------
Procedure majListBoxClient()
ClearGadgetItemList(#Tree_0)
ForEach Client()
nom_affiche.s = Client()\nom
; Si le client est en cours de ping mais ne répond pas...
If Date() - Client()\last_action_date > #TimeOutPing And Client()\ping_sent = 1
nom_affiche + " [Inactif]"
EndIf
AddGadgetItem(#Tree_0, -1, nom_affiche, 0, 0)
Next
EndProcedure
Procedure majEtatReseau()
ClearGadgetItemList(#Listview_1)
; Etat serveur
msg.s = "Etat du serveur : "
If Serveur : msg + "Activé" : Else : msg + "Désactivé" : EndIf
AddGadgetItem(#Listview_1, -1, msg)
If Serveur
msg = "Port : " + Str(Port)
AddGadgetItem(#Listview_1, -1, msg)
EndIf
; Etat reseau
AddGadgetItem(#Listview_1, -1, "")
msg = "Réseau : "
If Network : msg + "Connecté" : Else : msg + "Déconnecté" : EndIf
AddGadgetItem(#Listview_1, -1, msg)
msg = "Clients connus : " + Str(CountList(Client()))
AddGadgetItem(#Listview_1, -1, msg)
; Met à jour ici la list box contenant les clients
majListBoxClient()
EndProcedure
;- ===== Debut du programme =====
; ----------------------------------------------------------------------------
InitNetwork()
;Serveur = CreateNetworkServer(#PB_Any, #Port, #PB_Network_UDP)
; Ouverture de l'interface principale
Open_Window_9()
majEtatReseau()
If Serveur
SetGadgetText(#Button_48, "Couper le serveur")
Else
SetGadgetText(#Button_48, "Démarrer le serveur")
EndIf
Repeat
;- Gestion des évènements liés à la fenêtre
; ----------------------------------------------------------------------------
EventID = WaitWindowEvent(10)
Select EventID
Case #PB_Event_CloseWindow
End
Case #PB_Event_Gadget
Select EventGadget()
Case #Button_47 ;- Connecter au réseau
; ----------------------
; Active d'abord le serveur avant de tenter une connexion
; -----------------------
If Serveur = 0
sPort.l = Val(GetGadgetText(#String_104))
Serveur = CreateNetworkServer(#PB_Any, sPort, #PB_Network_UDP)
If Serveur
Port = sPort
EndIf
Else
CloseNetworkServer(Serveur)
EndIf
majEtatReseau()
If Serveur
SetGadgetText(#Button_48, "Couper le serveur")
Else
SetGadgetText(#Button_48, "Démarrer le serveur")
EndIf
connect_ip.s = GetGadgetText(#String_101)
connect_port.l = Val(GetGadgetText(#String_98))
username.s = GetGadgetText(#username)
If connect_ip And connect_port
; Envoi des données
; Sémaphore pour vérrouiller l'accès aux données
Sem_Acquire(AccessThreadParameters)
ThreadParameters.THREADPARAMETERS
ThreadParameters\connect_ip = connect_ip
ThreadParameters\client_port = connect_port
ThreadParameters\requete_type = #Connect
ThreadParameters\param1 = username
; Création du thread
CreateThread(@CreateRequete(), @ThreadParameters)
Network = 1
Else
MessageRequester("Connexion au serveur...", "Connexion au serveur impossible, il manque des données. Veuillez renseigner [IP | HOTE] : PORT", #MB_ICONEXCLAMATION)
EndIf
Case #Button_48 ;- Activer le serveur
If Serveur = 0
sPort.l = Val(GetGadgetText(#String_104))
Serveur = CreateNetworkServer(#PB_Any, sPort, #PB_Network_UDP)
If Serveur
Port = sPort
EndIf
Else
CloseNetworkServer(Serveur)
Serveur = 0
EndIf
majEtatReseau()
If Serveur
SetGadgetText(#Button_48, "Couper le serveur")
Else
SetGadgetText(#Button_48, "Démarrer le serveur")
EndIf
EndSelect
EndSelect
;- Gestion des évènements liés au réseau
; ----------------------------------------------------------------------------
; Uniquement si le serveur est connecté et disponible
If Serveur
;Debug "Server lancé sur le port " + Str(#Port)
Delay(10)
Event.l = NetworkServerEvent()
Select Event
Case 0
Case #PB_NetworkEvent_Connect ; : Un nouveau client s'est connecté au serveur.
; Pas d'évenement dans ce cas la.
; La connexion est acceptée mais on ne fait rien, on attend de voir ce que ce client veut !
Debug "Client connect"
Case #PB_NetworkEvent_Data ;: Des données ont été reçues (à lire avec ReceiveNetworkData())
; On retrouve l'envoyeur
clientID.l = EventClient()
clientIP.l = GetClientIP(clientID)
clientPort.l = GetClientPort(clientID)
; on lit les données
#Buffer_size = 65536
*buffer = AllocateMemory(#Buffer_size)
octets_lus.l = ReceiveNetworkData(clientID, *buffer, #Buffer_size)
If octets_lus => #Buffer_size
; ***********************************************
; Mémoire tampon insuffisante !!!
; Veuillez augmenter la taille de cette mémoire
; ***********************************************
EndIf
;- ### TYPE PACKET
; Type du message
; Effectue l'action qui va bien en fonction de l'entête du message
Select GetNetworkPacketType(*buffer)
;- #Connect
Case #Connect
; Format : CONNECT|REMOTE_SERVER_PORT(long)|NAME(str)|PASSWORD(str)
; Port du serveur du client
dataPacketPort.l = PeekL(*buffer + 4) ; 4 = sizeOf(Long)
; Lit le nombre d'octet à lire
octet_a_lire = PeekL(*buffer + 8)
nom.s = PeekS(*buffer + 12, octet_a_lire)
; Lit le mot de passe
octet_a_lire2 = PeekL(*buffer + 12 + octet_a_lire)
password.s = PeekS(*buffer + 16 + octet_a_lire, octet_a_lire2)
; **** RESEAU SECURISE ***
;If Network_Password = password
; Ajoute le client à notre liste (s'il n'existe pas déjà)
AddClient(clientID, clientIP, dataPacketPort, nom, Date())
;EndIf
; Met à jour CGC
ClientLastAction(clientID, clientIP, dataPacketPort, #Connect, Date())
majEtatReseau()
; Ecriture dans le log
Logs("[in] CONNECT : " + IPString(clientIP) + ":" + Str(dataPacketPort) + ", user:" + nom)
; Renvoi au nouveau client la liste des clients connus
; -----------------------------------------------------
clt_list = AllocateMemory(CountList(Client()) * SizeOf(CLIENT) + 8)
FirstElement(Client())
CopyMemory(@Client(), @clt_list, CountList(Client()) * SizeOf(CLIENT))
; CTL_LIST contient désormais tous les clients connus
; Sémaphore pour vérrouiller l'accès aux données
Sem_Acquire(AccessThreadParameters)
ThreadParameters.THREADPARAMETERS
ThreadParameters\client_ip = clientIP
ThreadParameters\client_port = dataPacketPort
ThreadParameters\requete_type = #Clients
ThreadParameters\param2 = @clt_list; pointeur sur la liste des clients
; Création du thread
CreateThread(@CreateRequete(), @ThreadParameters)
; Envoi au client nouvellement connecté le pseudo
; Sémaphore pour vérrouiller l'accès aux données
Sem_Acquire(AccessThreadParameters)
ThreadParameters.THREADPARAMETERS
ThreadParameters\client_ip = clientIP
ThreadParameters\client_port = dataPacketPort
ThreadParameters\requete_type = #Name
ThreadParameters\param1 = GetGadgetText(#username) ; le pseudo qui sera affiché chez le client
; Création du thread
CreateThread(@CreateRequete(), @ThreadParameters)
;- #Disconnect
Case #Disconnect
; Format : DISCONNECT|REMOTE_SERVER_PORT(long)
; Port du serveur du client
dataPacketPort.l = PeekL(*buffer + 4) ; 4 = sizeOf(Long)
RemoveClient(clientIP, dataPacketPort)
majEtatReseau()
; Ecriture dans le log
Logs("[in] DISCONNECT : " + IPString(clientIP) + ":" + Str(dataPacketPort))
;- #Clients
Case #Clients
Debug "Clients"
; Format CLIENTS|NB_CLIENTS(long)|IP(long)|PORT(long)|NAME(str)|[...]
; Port du serveur du client
dataPacketPort.l = PeekL(*buffer + 4) ; 4 = sizeOf(Long)
; Récupère la liste de tous les clients connus par un noeud du réseau
nb_clients.l = PeekL(*buffer + 8)
idx.l = 0
delta_nom.l = 0
While idx < nb_clients
ip.l = PeekL(*buffer + 12 + delta_nom)
port_.l = PeekL(*buffer + 16 + delta_nom)
octet_a_lire = PeekL(*buffer + 20 + delta_nom)
nom.s = PeekS(*buffer + 24 + delta_nom, octet_a_lire)
delta_nom + 13
delta_nom + octet_a_lire
idx + 1
; Ajoute le client à la liste s'il n'existe pas
AddClient(0, ip, port_, nom, Date(), #None)
Wend
; Ajoute le client qui envoi ces paquets
AddClient(0, clientIP, dataPacketPort, "(default)", Date(), #None)
; Ecriture dans le log
Logs("[in] CLIENTS : " + IPString(clientIP) + ":" + Str(dataPacketPort))
majEtatReseau()
;- #Message
Case #Message
; Format MESSAGE|REMOTE_SERVER_PORT(long)|DESTINATION(byte)|MESSAGE(str)
; Destination permet de savoir si c'est un message privé ou public ([0 | 1])
;- #File
Case #File
;- #Ping
Case #Ping
; Format PING|REMOTE_SERVER_PORT(long)
; Déclenche l'envoi d'un PONG vers l'envoyeur:)
dataPacketPort.l = PeekL(*buffer + 4) ; 4 = sizeOf(Long)
; Sémaphore pour vérrouiller l'accès aux données
Sem_Acquire(AccessThreadParameters)
ThreadParameters.THREADPARAMETERS
ThreadParameters\client_ip = clientIP
ThreadParameters\client_port = dataPacketPort
ThreadParameters\requete_type = #Pong
; Création du thread
CreateThread(@CreateRequete(), @ThreadParameters)
; Met à jour CGC
ClientLastAction(clientID, clientIP, dataPacketPort, #Ping, Date())
; Ecriture dans le log
Logs("[in] PING : " + IPString(clientIP) + ":" + Str(dataPacketPort))
; Mise à jour de l'interface
majEtatReseau()
;- #Pong
Case #Pong
; Format PONG|REMOTE_SERVER_PORT(long)
; Réponse à un PING (ou pas ;)). Donne l'information comme quoi le client est tjs connnecté sur le réseau
; Port du serveur du client
dataPacketPort.l = PeekL(*buffer + 4) ; 4 = sizeOf(Long)
; Modifie les données du client
ClientLastAction(clientID, clientIP, dataPacketPort, #Pong, Date())
; Ecriture dans le log
Logs("[in] PONG : " + IPString(clientIP) + ":" + Str(dataPacketPort))
; Mise à jour de l'interface
majEtatReseau()
;- #Name
Case #Name
; Format NAME|REMOTE_SERVER_PORT(long)|NOM(str)
; Modification du nom visible par tous
; Port du serveur du client
dataPacketPort.l = PeekL(*buffer + 4) ; 4 = sizeOf(Long)
; Lit le nombre d'octet à lire
octet_a_lire = PeekL(*buffer + 8)
nom.s = PeekS(*buffer + 12, octet_a_lire)
; Modifie le client de notre liste (s'il n'existe pas déjà)
ModifClient(clientID, clientIP, dataPacketPort, nom, Date(), #Name)
; Ecriture dans le log
Logs("[in] NAME : " + IPString(clientIP) + ":" + Str(dataPacketPort))
; *********************** ADMIN ONLY *****************************************
;- #Network_Password
Case #Network_Password
; Format NETWORK_PASSWORD|OLD_PASS(str)|NEW_PASS(str)
; Change le mot de passe pour entrer sur le réseau
EndSelect
Case #PB_NetworkEvent_File ;: Un fichier a été reçu (à lire avec ReceiveNetworkFile())
Case #PB_NetworkEvent_Disconnect
EndSelect
;- CGC Client Garbage Collector
; Gestion des clients
; Ping / Pong
ForEach Client()
; Timeout de suppression du client
If Date() - Client()\last_action_date > #TimeOut
Debug "Suppression du client [cause : inactivité]"
DeleteElement(Client()) ; Supprime le client et passe au suivant
majEtatReseau()
Continue
EndIf
; Si le timeout d'envoi d'un ping est dépassé et que celui ci n'a pas déjà été envoyé
If Date() - Client()\last_action_date > #TimeOutPing And Client()\ping_sent = 0
; Pour chaque client on va créer un thread pour l'envoi d'une requete
; Créé une zone mémoire avec les infos à passer aux threads
; et la vérrouille afin que le thread est le temps de lire
;LockMutex(AccessThreadParameters)
Sem_Acquire(AccessThreadParameters)
ThreadParameters.THREADPARAMETERS
ThreadParameters\client_ip = Client()\ip
ThreadParameters\client_port = Client()\port
ThreadParameters\requete_type = #Ping
; Interdit le ping jusqu'à ce qu'une réponse soit recue
Client()\ping_sent = 1
; Création du thread
CreateThread(@CreateRequete(), @ThreadParameters)
majEtatReseau()
EndIf
Next
EndIf ; Fin gestion du serveur
ForEver
End