PureBasic

Forums PureBasic
Nous sommes le Sam 15/Déc/2018 7:46

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 11 messages ] 
Auteur Message
 Sujet du message: Application client-serveur et événements
MessagePosté: Mer 10/Oct/2018 14:45 
Hors ligne

Inscription: Lun 10/Juin/2013 12:01
Messages: 33
Bonjour/bonsoir,
Client et utilisateur de PureBasic depuis de nombreuses années, je me trouve face à une situation bloquante en programmation client serveur. Et ce à cause de la gestion du réseau par événements dans purebasic.
Je vous présente mon objectif :
avoir une application serveur qui écoute uniquement sur le port 2018 (par exemple)
avoir une application client A qui transmet à intervalles réguliers des données d'une taille L sur le port 2018
avoir une application client B qui transmet à intervalles réguliers des données d'une taille ~L sur le port 2018
A reçoit ce que B envoie grâce à l'application serveur
B reçoit ce que A envoie grâce à l'application serveur
avoir une application cliente C qui reçoit la moyenne des valeurs envoyées par A et B grâce à l'application serveur. Si B n'envoie rien alors C recevra uniquement ce que A envoie. Si A n'envoie rien alors C recevra uniquement ce que B envoie.

Par exemple
A envoie 1020304050
B envoie 60708090A0
C recevra 3848586878 (ou calculera par lui même ces valeurs)

Tout mon problème réside dans la réalisation, coté serveur, de la moyenne. En effet lorsque je lis les événements réseaux, coté serveur, du client A je n'ai la possibilité que plus loin dans mon code de voir s'il y a des données envoyées au serveur par le client B. Du coup je suis bien embêté. La documentation informe qu'il faut appeler ReceiveNetworkData() uniquement après avoir reçu un événement #PB_NetworkEvent_Data. Cette manière de structurer le code par événement m’empêche de réaliser mon objectif.

Dois-je plutot tenter de faire en sorte que la moyenne soit calculée par l'application cliente C?
En y pensant je me dis que placer un header dans le paquet contenant un identifiant attribué par le serveur permettrait de savoir quel client envoie quoi. Mais lorsque A et B enverront des données comment C fera-t-il apres avoir reçu un paquet de A pour savoir qu'il y a un autre paquet en attente de la part de B? Je n'ai jamais eu de mal avec une application réseau mais dans ce cas, devoir structurer avec des evenements me pose de gros soucis. C'est pourquoi je fais appel à votre aide. Je n'attends pas particulièrement un code en réponse, mais plus une idée, une manière de faire....mais pourquoi pas du code si c'est plus simple de répondre ainsi pour vous. Je vous remercie et vous souhaite une bonne journée.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Mer 10/Oct/2018 16:04 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1433
Je ne suis pas sûr de tout bien comprendre :?

Tout comme un évènement Windows retourne l'évènement ET l'ID la fenêtre concernée,
un évènement réseau retourne les données ET l'ID du client, même s'il y en a plusieurs.

Chaque paquet est identifié et tu peux savoir si un client est connecté ou pas.
Donc un moyen est de détecter si les clients A et B a se sont déconnectés avant de faire les moyennes

Voici un exemple de serveur et client, dérivé de ceux de la doc
(J'ai surtout remplacé les MessageRequester par des Debug pour voir tous les messages ensembles)
Code:
Debug "SERVEUR"
InitNetwork()

Port = 6832
*Buffer = AllocateMemory(1000)

If CreateNetworkServer(0, Port)
    Repeat   
        SEvent = NetworkServerEvent()
        ClientID = EventClient()
        Select SEvent
            Case #PB_NetworkEvent_None
                Delay(10)
               
            Case #PB_NetworkEvent_Connect
                Debug "A new client has connected !"
               
            Case #PB_NetworkEvent_Data
                ReceiveNetworkData(ClientID, *Buffer, 1000)
                Debug "Client: " + ClientID + " a envoyé: " + PeekS(*Buffer, -1, #PB_UTF8)
               
            Case #PB_NetworkEvent_Disconnect
                Debug "Client: "+Str(ClientID)+" has closed the connection..."
                ; Quit = 1
               
        EndSelect
    Until Quit = 1
    CloseNetworkServer(0)
Else
    Debug "Can't create the server (port in use ?)."
EndIf

End

Code:
;Debug "CLIENT"
InitNetwork()
Port = 6832

ConnectionID = OpenNetworkConnection("127.0.0.1", Port)
If ConnectionID
  SendNetworkString(ConnectionID, "Données de A" + Chr(0), #PB_UTF8)
  CloseNetworkConnection(ConnectionID)
EndIf

ConnectionID = OpenNetworkConnection("127.0.0.1", Port)
If ConnectionID
  SendNetworkString(ConnectionID, "Données de B" + Chr(0), #PB_UTF8)
  CloseNetworkConnection(ConnectionID)
EndIf

Lance le serveur puis le client, cela te donnera des indications sur les infos échangées.

Si ça peut t'aider (je débute en application réseau en PB)

:wink:

Edit Corrigé suite à suggestion bobby.
Supression If SEvent et ajout Case #PB_NetworkEvent_None : Delay(10)
La charge CPU passe de 25 à 0.17% !


Dernière édition par Marc56 le Jeu 11/Oct/2018 16:14, édité 3 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Mer 10/Oct/2018 17:11 
Hors ligne

Inscription: Jeu 07/Juin/2007 22:54
Messages: 206
@Marc56 n'ayant pas de waitnetworkevent, je te conseille (coté serveur) de rajouter un case #PB_NetworkEvent_None : delay(xx)
Ca évitera d'avoir un serveur à 100% CPU pour rien.

@salutcava https://www.purebasic.fr/french/viewtopic.php?f=1&t=17377&start=3
Un exemple fonctionel de relation client serveur...


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Mer 10/Oct/2018 22:02 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 11/Fév/2005 17:34
Messages: 4148
Localisation: Arras, France
Au niveau algo, je pense que tu dois donner un numéro à tes paquets, de façon à pouvoir faire les moyennes dans l'ordre par le serveur. Par exemple si les clients a et b envoient plusieurs nombres à la suite, la moyenne ne sera pas forcément bonne car le tcp/ip ne garantit pas l'ordre d'arrivée des paquets. Pour que cela fonctionne, il faut que tu ajoutes à tes nombres un numéro d'ordre. Par exemple, A envoie 1-123, B envoie 1-456, A envoie 2-765, B envoie 2-876 etc... La moyenne 1 sera (123+456)/2, la moyenne 2 sera (765+876)/2 etc.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Mer 10/Oct/2018 22:33 
Hors ligne

Inscription: Lun 10/Juin/2013 12:01
Messages: 33
Merci pour vos réponses marc, boby et djes.
Merci djes pour ton idée de donner un ordre aux paquets des deux clients émetteurs.
Je vais voir si je peux m'en sortir en suivant cette approche.
Merci!


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Jeu 11/Oct/2018 8:30 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1433
(Supprimé. Réponse 1 modifiée avec les suggestions de Boby :wink: )


Dernière édition par Marc56 le Jeu 11/Oct/2018 16:40, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Jeu 11/Oct/2018 9:41 
Hors ligne

Inscription: Jeu 07/Juin/2007 22:54
Messages: 206
@Marc
Code:
SEvent = NetworkServerEvent()
If SEvent
[...]
EndIf

Code:
Debug #PB_NetworkEvent_None

:wink:

C'est vraiment préférable de gérer le delay via l'event (ou plutot le non event) #PB_NetworkEvent_None que dans ta boucle principale, en cas de transfert de gros paquet, si tu delay est dans ta boucle, tu auras ton delay entre chaques ReceiveNetworkData(), alors que si tu met un delay uniquement si il n'y a pas d'activité réseau, bah tant qu'il y a du boulot pour le serveur, il va bosser, sans attendre 10 ms entre chaques écoute réseau. (J'suis d'accord que 10ms c'est vraiment quedal, mais sur un serveur qui se retrouve à gérer beaucoup de connexion, ça doit se sentire à un moment je pense...)


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Ven 12/Oct/2018 6:21 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1433
Citation:
SEvent = NetworkServerEvent()
If SEvent

Debug #PB_NetworkEvent_None

Merci pour la réponse didactique, ça force à analyser plutôt que recopier :)
Pour une fois ce sont des lignes en trop qui bloquaient :P
Effectivement pour traiter #PB_NetworkEvent_None (= 0) il faut d'abord entrer dans la boucle Select, donc SEvent <> 0. Logique!
Ça fonctionne bien maintenant, tous mes programmes réseaux tournent à environ 0.17% de CPU contre 24% avant.

:wink:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Ven 12/Oct/2018 7:11 
Hors ligne
Avatar de l’utilisateur

Inscription: Ven 11/Fév/2005 17:34
Messages: 4148
Localisation: Arras, France
Pour ton problème de qui envoie quoi, il suffit d'imaginer une conversation à 4 par courrier : on met sur l'enveloppe le nom du destinataire, de l'expéditeur et la date. Pour transférer un courrier, tu le joins en entier. De cette manière, le destinataire peut tout déduire.

Pour ton problème de moyenne qui ne se fait que si a et b ont répondu, il faut forcément que cela soit rattaché à autre chose de commun, pour que les réponses soient coordonnées. Soit un numéro d'ordre, soit un numéro extérieur ou un signal commun. C'est difficile de dire mieux sans savoir à quoi ça se rapporte.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Mar 16/Oct/2018 2:48 
Hors ligne

Inscription: Lun 10/Juin/2013 12:01
Messages: 33
Voici plus d'informations sur le problème que je rencontre. Lors de mon tout premier poste j'ai essayé de simplifier au maximum mon vrai probleme.
Il se trouve que les données envoyées sont des données audio. Et donc la moyenne n'est pas une moyenne mais de quoi "mixer" les données audio.
Voilà tout.
Peut etre que le mix (la moyenne) devrait se faire coté serveur du coup?
Toujours est-il que j'ai ajouté en entete de mes données audio un identifiant unique aux émetteurs , comme suggéré dans une des réponses proposées.
Je vais voir comment je peux m'en sortir avec cette approche.
(je n'ai pas avancé plus ayant manqué de temps....(eh oui Black OPS 4 est sorti... :( )


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Application client-serveur et événements
MessagePosté: Ven 19/Oct/2018 19:55 
Hors ligne

Inscription: Lun 10/Juin/2013 12:01
Messages: 33
Bonjour/Bonsoir,
Je reviens vers vous pour vous donner des nouvelles :D
De la manière que j'envisageais les choses...ca aurait été compliqué d'arriver à mes fins. Il aurait fallu identifier les émetteurs des packets audio et calculer leur durée et mixer le son etc etc
HEUREUSEMENT que le codec son que j'utilise gère le multistream...du coup tout va bien le problème est résolu. Les paquets arrivent les uns à la suite des autres et tout est géré automatiquement...Ahhhh les library...qu'est ce qu'on ne ferait pas sans elles....Cependant faire les choses par soit même à son petit coté stimulant qui ne me deplait pas :)
Les paquets arrivent donc les uns à la suite des autres et le multistream est géré sans soucis.
Merci à vous pour vos réponses, je vous aime. Bisous!
Vive Purebasic, je kiffe depuis des années!


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 11 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 3 invités


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  
cron

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye