PureBasic

Forums PureBasic
Nous sommes le Mar 19/Jan/2021 16:39

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 14 messages ] 
Auteur Message
 Sujet du message: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Lun 11/Mai/2020 9:31 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 34
Bonjour,

Je souhaiterais créer un binôme client/serveur en TCP. Sachant que je pourrais avoir simultanément 1200 clients connectés (au maximum) sur un LAN, quels sont les points auxquels je dois faire attention ? Par exemple, j'ai lu sur le forum que certains créent une thread par connexion.
La partie serveur afficherait la liste des client connectés et permettrait des envois de commandes aux clients sélectionnés.
La partie cliente ferait remonter au serveur des infos techniques et donc exécuterait aussi les commandes reçues du serveur.
Quelle est la meilleure approche ?

En vous remerciant par avance.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Lun 11/Mai/2020 17:21 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1865
Bonjour tatanas,

1200 clients et un serveur, ce n'est plus un binôme :P

Je ne pense pas que créer un thread par connexion soit une bonne idée (ni même faisable étant donné qu'il est possible que chaque thread se réserve un espace mémoire). (pas testé)

S'il s'agit comme pour l'un de tes projet de la gestions de périphériques par SNMP, je pense que le mieux est de faire du pooling SNMP dans le sens application vers les clients et d'utiliser les traps SNMP dans le sens client vers serveur (si les clients ont ce dispositif: les imprimantes réseau l'ont par exemple souvent)

:wink:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Lun 11/Mai/2020 18:21 
Hors ligne
Avatar de l’utilisateur

Inscription: Mer 24/Aoû/2005 10:42
Messages: 518
Tu peux aussi jeter un oeil ici : https://www.purebasic.fr/english/viewto ... 536083355b

(je ne sais absolument pas si ça peut répondre à ta demande !!)

_________________
Bureau : Win10 64bits
Maison : Macbook Pro 13" Retina / SSD 512 Go / Ram 16 Go - iPad Pro 32 Go (pour madame) - iPhone X 256 Go


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 8:41 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 34
Ce n'est pas un projet lié au snmp. Juste un moyen de récupérer des infos de postes clients sous Windows et leur transmettre des commandes à exécuter en local.
Donc clairement les requêtes partiraient des clients pour "alimenter" le serveur et parfois le serveur enverrait des ordres aux clients.

Lien intéressant pour des envois de données TCP supérieurs à 65536 octets ce qui semble être la limite des fonctions Purebasic.

Petite question liée à ce sujet : Comment doit on gérer la réception de données lorsque celles-ci sont incomplètes ? J'ai regardé quelques exemples de codes sur le forum mais les gens n'ont pas l'air de s'en soucier. Est-ce que ce genre de traitement convient ?
Code:
; réception de données envoyées par un SendNetworkString() en UTF8

DataReceived = ReceiveNetworkData(connectionID, *BufferReceive, BufferLen)
While DataReceived = BufferLen
   resultat = resultat + PeekS(*BufferReceive, -1, #PB_UTF8)
   DataReceived = ReceiveNetworkData(connectionID, *BufferReceive, BufferLen)
Wend

; traitement de resultat


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 10:20 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1865
Citation:
Juste un moyen de récupérer des infos de postes clients sous Windows et leur transmettre des commandes à exécuter en local.
Tu ne veux pas utiliser les webservices (HTTPRequest()) ? cela serait bien plus simple et rapide à mettre en œuvre et à modifier. Tu peux écrire la partie serveur en PB ou utiliser un simple serveur web et un langage dynamique ou CGI.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 10:42 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 34
Disons que ça permettrait aux clients d'envoyer facilement les infos au serveur (web) mais le serveur ne pourrait envoyer ses ordres aux clients que si ces derniers hébergent aussi un serveur web, non ?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 11:00 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1865
tatanas a écrit:
Disons que ça permettrait aux clients d'envoyer facilement les infos au serveur (web) mais le serveur ne pourrait envoyer ses ordres aux clients que si ces derniers hébergent aussi un serveur web, non ?
Le principe du webservice c'est une question/réponse.
Le client envoie la question par GET ou POST (dans l'URL ou dans le corps)
Le serveur répond par une page unique formatée (texte, html, json, xml)
À partir de là, il suffit que le client analyse le contenu de la réponse et exécute l'ordre reçu.

La seule différence par rapport au web normal c'est qu'on n'utilise pas de navigateur. C'est au client (programme) de voir ce qu'il veut faire avec le fichier reçu. Donc ici, par exemple tu utilises un FindString() pour lire une commande dans le texte que tu utilises ensuite dans RunProgram()

:wink:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 12:42 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 34
Je comprends bien. Mais le client ne sait pas à priori quand il va recevoir un ordre. Or dans le cas que tu expliques, il devrait envoyer une requête au serveur pour savoir si le serveur veut lui donner un ordre. Du coup il faudrait sonder très régulièrement le serveur pour être réactif à un ordre qui pourrait être donné une fois par mois comme plusieurs fois par jour. Est-ce un fonctionnement très propre ?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 12:51 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1865
Je partais de l'hypothèse que c'était le client qui initialisait une connexion et devait faire quelque-chose en fonction de la réponse serveur (exemple: Windows update où le client va voir ce qui est dispo, puis charge et installe seul)

Si le serveur qui doit aussi pouvoir atteindre le client à tout moment alors il faut que le client se comporte effectivement comme un serveur.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 13:08 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 34
Donc, je reste sur mon client/serveur TCP.
Concernant ma question au sujet de ReceiveNetworkData(). Quelle est la bonne méthode pour être certain que toutes les données sont bien arrivées ?
J'ai du mal à me rendre compte comment PureBasic gère cela en interne. Il est bien indiqué dans la doc de ReceiveNetworkData() : "If 'Result' is equal to DataBufferLength then more data is available to be read". Mais puisque ReceiveNetworkData() n'est censé être appelé qu'après la réception de #PB_NetworkEvent_Data, ma boucle while n'a peut être aucun intérêt ?


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 14:35 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1865
Tu peux mettre un buffer plus grand que la taille maxi du message à recevoir et couper le message à la longueur des octets réellement reçus (retournée par ReceiveNetworkData()) donc pas besoin de boucle.

Exemple (basé sur les deux exemples de la doc)

Lancer le serveur, puis le client
Serveur
Code:
If InitNetwork() = 0
    MessageRequester("Error", "Can't initialize the network !", 0)
    End
EndIf

Port = 6832
*Buffer = AllocateMemory(1000)

If CreateNetworkServer(0, Port)
   
   Debug "Server created (Port " + Str(Port)+")."
   
    Repeat
       
        SEvent = NetworkServerEvent()
       
        If SEvent
           
            ClientID = EventClient()
           
            Select SEvent
                   
                Case #PB_NetworkEvent_Connect
                    Debug "Server - A new client has connected ! " + Str(ClientID)
                   
                Case #PB_NetworkEvent_Data
                    Nb_Octets = ReceiveNetworkData(ClientID, *Buffer, 1000)
                    ;Debug "Reçu: ("+ Nb_Octets +") >>>" + PeekS(*Buffer, -1, #PB_UTF8) + "<<<"
                    Debug "Reçu: ("+ Nb_Octets +") >>>" + PeekS(*Buffer, Nb_Octets, #PB_UTF8) + "<<<"
                   
                Case #PB_NetworkEvent_Disconnect
                    Debug "Client "+Str(ClientID)+" has closed the connection..."
                    Quit = 1
                   
            EndSelect
        EndIf
       
    Until Quit = 1
   
    Debug "PureBasic - Server: END"
   
    CloseNetworkServer(0)
Else
    MessageRequester("Error", "Can't create the server (port in use ?).", 0)
EndIf

End   
Avec PeekS(*Buffer, -1, #PB_UTF8) tu recois la totalité du buffer.
Avec un buffer plus petit que le plus grand message, je pense que tu devrais effectivement boucler et probablement tester un caractère de fin qui serait à ajouter (EOT ? ETX ?)

Client
Code:
If InitNetwork() = 0
    MessageRequester("Error", "Can't initialize the network !", 0)
    End
EndIf

NewList Jour$()
AddElement(Jour$()) : Jour$() = "Lundi"
AddElement(Jour$()) : Jour$() = "Mardi"
AddElement(Jour$()) : Jour$() = "Mercredi"
AddElement(Jour$()) : Jour$() = "Jeudi"
AddElement(Jour$()) : Jour$() = "Vendredi"
AddElement(Jour$()) : Jour$() = "Samedi"
AddElement(Jour$()) : Jour$() = "Dimanche"

Port = 6832
ConnectionID = OpenNetworkConnection("127.0.0.1", Port)
If ConnectionID
   
    ForEach Jour$()
        SendNetworkString(ConnectionID, Jour$(), #PB_UTF8)
        Delay(1000)
    Next
   
    CloseNetworkConnection(ConnectionID)
Else
    MessageRequester("PureBasic - Client", "Can't find the server (Is it launched ?).", 0)
EndIf

End   

J'ai peut -être encore répondu à coté, mais ça m'a permis de comprendre des trucs nouveaux
Je n'ai jamais fais d'application client/serveur purement en PB, mais ceci fonctionne.
Tiens, je vais créer mon propre ICQ en PB :mrgreen:


Dernière édition par Marc56 le Mar 12/Mai/2020 14:55, édité 1 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 14:53 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 34
En effet ça fonctionne ainsi et la logique se tient :)

En fouinant j'ai aussi trouvé ce lien : http://forums.purebasic.com/english/vie ... 7e1ff8c70b
Il s'avère qu'il y a un soucis lorsque le nombre de bytes retournés par ReceiveNetworkData() est la même que la taille du buffer ET que le paquet envoyé fait aussi cette taille.
Du coup on ne peut pas déterminer si la réception est bien terminée ou s'il en reste, mais si on relance un ReceiveNetworkData(), alors on reste bloqué sur cette fonction qui attends que d'autres données arrivent alors qu'il n'y a plus rien à recevoir.
Et en page 2 une solution qui permet de connaitre le nombre de bytes en attente dans le socket, ce qui permet d'allouer un buffer de la bonne taille directement.


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 15:18 
Hors ligne

Inscription: Sam 08/Fév/2014 15:19
Messages: 1865
Perso j'aime pas trop mettre des API directes, je préfère utiliser les pièces d'origine certifiés par Fred 8)

Cela dit, comme c'est toi qui fera l'application client et celle du serveur, tu peux fixer d'autorité la taille des chaines envoyées et celle du buffer.

Au besoin, tu mets un caractère de fin (ex: Chr(4) = EOT (End Of Transmission) ou ETX etc, c'est fait pour ne pas être confondu avec le reste et tu le teste à l'arrivée comme dernier caractère du tampon (Right())

Quelque-chose comme ça
Code:
Tmp_Buf = PeekS(*Buffer, Nb_Octets -1, #PB_UTF8)
If Right(Tmp_Buf , 1) = Chr(4) : Break : EndIf

(pas testé)

:wink:


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: Demande de conseil pour mise en place client/serveur tcp
MessagePosté: Mar 12/Mai/2020 16:02 
Hors ligne

Inscription: Mar 05/Nov/2019 18:40
Messages: 34
Oui je vais peut être faire ça.
Et vu que l'un des clients de ce serveur sera un module d'administration, je pense qu'il requêtera le serveur en webservices puisqu'il ne fera que récupérer des données.
Un pti mix des 2 solutions finalement.


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

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 6 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 à:  

 


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