Socket Serveur-Client

Soyez le premier à donner votre avis sur cette source.

Vue 7 768 fois - Téléchargée 1 897 fois

Description

Bonjour, je depose deux sources sur la programmation réseau. La premiere source
est le client qui s'occupe de se connecter au serveur et de lui envoyer un
message, quitte quand on envoit "007". Le serveur se lie a un port et ecoute,
accepte la connexion du client, reçoit ses messages et les affiches. Je tiens a
preciser qu'il faut demarrer le serveur avant le client et que je ne suis pas
fan de James Bond.

Codes Sources

A voir également

Ajouter un commentaire Commentaires
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
Hors-sujet ? 
oui ^^

je vais pas trop parler, au final on dit la même chose avec des termes différents.
Juste comme ca, epoll permet de gérer les événements et donc travaille bien en parallèle (tu n'utilise pas les thread directement mais au final tu en as bien qui gèrent tes connexion / événements / pile / etc. ). Ce n'est pas parce qu'on ne voit ce qu'utilise nos composants qu'il faut l'ignorer.
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120
Au début, je fais un client mono-thread (voir la solution "sans thread, ni fork"), puis un multi-thread pour l'exemple (et aussi car le demandeur voulait gérer des demandes lourdes). Mais je précise bien qu'un client mono-threadé est non seulement viable, mais parfois plus adapté.

C'est la méthode kernel utilisée (select ou epoll) non bloquante qui est d'une certaine manière threadée (pour vulgariser) qui se charge de recevoir les clients en parallèle. Ensuite, si ton application mono-threadé ne gère pas des demandes trop lourdes (exit l'upload de fichier, mais ok pour du chat), alors elle va répondre séquentiellement à chacun de tes clients dans un temps imparti plus rapide que si tu te payais les switch de contexte kernel pour gérer X tâches en parallèles (dès le moment ou ton nombre de connexions > nombre de coeurs physiques). En d'autre terme, plus tu as de query par seconde, plus la concurrence coute cher en "context switching". Si tes tâches commencent à couter aussi cher en "context switching" que leur durée, tu perds en perfs.

Pour résumer: oui on peut faire un serveur mono-thread qui accepte plusieurs clients simultanéments (mais qui traite leur demande séquentiellement). C'est aussi la meilleure solution si les tâches a effectuer sont très courtes (quelques ms), mais très nombreuses (> 3000 query/secondes).

Je réponds ici, en écho à ton commentaire qui laisse penser, à tort, que "pas de multi-thread == pas de multi-clients (viable)". Il est important de préciser que le multi-thread et le multi-client sont deux notions différentes, pas forcément liées. Le choix du multi-threading ne doit pas être automatique, mais adaptée à la situation.
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16 >
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021

ok je vois ton point de vue. Pour la communication entre client, tu n'utilise pas la classe thread mais tu ordonne toi même le séquencement. Le soucis dans ce cas c'est qu'une pile se forme : oui tu ne veux pas utiliser un thread, mais quand le client envoi une trame il faut écouter. quand c'est de manière séquentiel, tu créé une latence : au lieu d'écouter, tu vas vérifier s'il y a eu un message et dans ce cas tu vas le traiter, sinon tu vas checker les autres et tu tourne => il n'y a donc pas de vrai blocage en soit vu qu'on effectue des tests plutôt qu'attendre, mais ca reste assez limité comme solution.

C'est la même chose pour les événements : tu ne gère peu être pas ce qui attends l'événement mais l'écoute est bien dans une tâche différente de ta tâche principale.


ton commentaire qui laisse penser, à tort, que "pas de multi-thread == pas de multi-clients (viable)"

c'est ce que je veux dire, mais en effet il faudrait le tourner plutôt en disant que sans utiliser les outils du multitâche, on réinvente ce qui existe (et il y a peu de chance , dans le cas où l'application est grosse et pourquoi pas interfacé dans une form, que ton code soit aussi performant).
alors oui dans l'absolu on peu même faire un client serveur en assembleur, mais c'est pas très pratique ><
Messages postés
3839
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
15 avril 2021
120 >
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021

Pour la communication entre client, tu n'utilise pas la classe thread mais tu ordonne toi même le séquencement.
Rien n'est réordonné par moi même. c'est bien le "epoll" qui se charge de l'ordonnancement.

Le soucis dans ce cas c'est qu'une pile se forme : oui tu ne veux pas utiliser un thread, mais quand le client envoi une trame il faut écouter. quand c'est de manière séquentiel, tu créé une latence
Je ne comprends pas ton argument, Le problème est très exactement le même avec du multi-threading. Il ne faut pas confondre concurrence et parallélisme. Ton nombre de coeur n'étant pas infini, tu ne peux pas avoir une parallélisation parfaite. Tu entres donc forcément dans un cas de concurrence, et le phénomène que tu décris se produit tout aussi bien en multi-threading. Si tu as 8 coeurs, et 9 clients, le 9ème client va de toute façon attendre.

mais ca reste assez limité comme solution.
C'est justement la raison pour laquelle je réponds en public: non, ce n'est ni une bidouille, ni une méthode "limitée". Ne pas faire de thread est parfois indispensable. Notamment dans certains domaines embarqués. J'ai un ami qui bosse actuellement sur un projet pour une grosse boîte (T**lès). Il développe une couche réseau pour communiquer efficacement entre deux appareils via des ondes radios (présence de multi-clients, forte charge possible). Il n'y a aucun thread. D'une part parce que ça coute "cher" (en terme de perfs sur des appareils faibles en puissance), d'autre part parce que c'est bien plus lent que de ne pas en faire, pour les raisons que j'ai déjà évoqué.

mais l'écoute est bien dans une tâche différente de ta tâche principale.
En mode mono-threadé, l'écoute est belle et bien en dehors de ta tâche principale. Voir le fonctionnement d'epoll, qui peut tout à fait être au courant de la disponibilité de plusieurs fd en parallèle. Tu peux voir epoll comme étant un outil multi-threadé "dans ton dos" par le kernel (ce qui n'est pas vrai, mais je me permet cette vulgarisation pour faciliter la compréhension).

[...] en effet il faudrait le tourner plutôt en disant que sans utiliser les outils du multitâche, on réinvente ce qui existe
Pas du tout. C'est juste un model différent pour un usage différent. Rien n'est réinventé.

(et il y a peu de chance , dans le cas où l'application est grosse et pourquoi pas interfacé dans une form, que ton code soit aussi performant).
Raison pour laquelle j'insiste: Rien à voir avec la taille de ton application, ou la présence ou non de "form". C'est l'usage que tu en fait qui fait le performance. Encore une fois, si tu as de très nombreuses tâches, très courtes, une appli mono-thread sera plus performante. Quant à la forme, elle aura certes son thread dédié pour ne pas "geler" l'affichage, mais la partie réseau aura aussi son seul thread dédié, si tu te trouves dans ce model.
Ne pas oublier que dans le model où tu reçois une quantité énorme de petites requêtes, tu seras "I/O bound" bien avant d'être "CPU bound". Or, tant que tu n'es pas "CPU bound", avoir 50 coeurs ne vas pas trop te servir...

alors oui dans l'absolu on peu même faire un client serveur en assembleur, mais c'est pas très pratique
Hors-sujet ?


====

Résumé pour le lecteur qui passerait sans vouloir se taper tout le pavé:
- Si nombreux clients donc nombreux appels ET requêtes traitées rapidement => Mono-thread plus rapide. Exemple (serveur de real-time bidding, echo server, etc...)
- Si requêtes moyennes/longues => Multi-thread plus rapide (upload de fichier, serveur de calcul qui répond une fois celui-ci fini, etc...).
Messages postés
4270
Date d'inscription
samedi 8 septembre 2007
Statut
Membre
Dernière intervention
4 mars 2021
16
@cptpingu: j'ai pas tout lu vu que je suis au taff, mais de ce que j'ai compris l'idée était de faire un système de pile pour traiter un connexion+demande à la fois. Le problème dans ce cas c'est que tu perds le principe de temps réel et tu va propager l'information de manière asynchrone entre les clients. Dans l'absolu, c'est de toutes facon plus ou moins le cas dans le sens où nos matos ne permettent pas de faire 8000 traitement parallèle (limité au nombre de coeur, donc 8 aujourd'hui si je ne m'abuse) et donc il n'y a pas de vrai synchro (après j'ai pas les compétences pour aller plus loin).
Ensuite, comment gère tu les nouveau clients sans thread (et évènement) ? si tes clients connecté ne peuvent rien faire car on attend une nouvelle connexion c'est pas top, trop procédural ... bon après si tu veux en parler il vaut mieux un post ou mp histoire de pas trop pourrir celui ci ^^
Afficher les 8 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.