IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau/Web Python Discussion :

Création serveur,multi thread, multi ports


Sujet :

Réseau/Web Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Janvier 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 24
    Par défaut Création serveur,multi thread, multi ports
    Bonjour à tous,

    J'ai joué avec pas mal de petits morceaux de code, trouvés de ci de là, pour créer une connexion socket. Toutefois je n'ai pas trouvé de programmes qui ressembleraient fortement à ce que j'ai besoin.
    Je vous explique ce que je désire faire avec certains impératifs dont je ne suis pas maitre.

    J'ai besoin d'un serveur qui puisse être connectés par 4 et seulement 4 clients sur 4 ports différents (10001 à 10004 obligatoire)
    Chaque client peut envoyer, à n'importe quel moment, une commande, sur une dizaine de caractères ASCII maxi terminé par le caractère spécial $10 (LF)

    Le serveur doit pouvoir recevoir cet ordre ou commande, et parfois, il réponds au client qui à lancé la requête et/ou execute l'ordre donné après l'avoir analysé.

    Je suppose que le serveur doit utiliser les threads ? C'est une chose que je ne pige pas trop.
    Si je comprends le thread, c'est une manière de faire travailler mes connexions en parallèle (4 threads pour 4 ports) avec mon prog principal qui:
    1: surveille si quelque chose est arrivé d'un socket
    2: execute les ordres
    Sans perturber/retarder ce qu'il peut faire éventuellement d'autre.
    C'est bien cela ?

    Je peux récupérer facilement sous forme de string par exemple, chaque réception ?

    Maintenant si plusieurs ordres arrivent en même temps de mes différents clients que se passe-t-il ?
    Vais-je en zapper ?
    Risquent-ils d'être altérés ?
    Je précise que chaque client envoie beaucoup d'ordres. Avec la latence d'un réseau cela peut être de l'ordre d'un ordre toutes les 100mSec, et que chaque client n'est forcément pas synchrone, cela peut faire beaucoup de choses à traiter.

    J'ai besoin aussi de savoir si une connexion s'est arrêtée (client deconnecté)

    Voilà, c'est pas quelque chose de commun semble-t-il puisque je n'ai pas trouvé de bout de codes qui y ressemblerait. Enfin je dis cela, c'est surtout, parce que je ne sais par quel exemple commencer, étudier, dégrossir et poser des questions pour apprendre, comprendre et me corriger. (et m'en souvenir, car j'ai ma ram perso qui oublie vite )

    Toute aide bienvenue

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur en formation
    Inscrit en
    Juillet 2013
    Messages
    300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en formation
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juillet 2013
    Messages : 300
    Par défaut
    Le but est de lancer 4 threads : un par client. Chacun écoute les données et agît en conséquence. J'imagine que la réaction va être la même pour chaque client pour une même requête donc il faut créer une classe qui hérite de Thread :
    (je n'ai pas étoffé, on peut rajouter des trucs, des try...)
    côté serveur, ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    import threading
    import socket
     
    class Client(threading.Thread):
        def __init__(self, conn):
    	threading.Thread.__init__(self)
    	self.connexion = conn		   # socket de connexion
     
        def run(self):
    	global truc #si tu as des variables globales à utiliser
    	while True :#j'imagine qu'on est à l'écoute en permanence
                commande=self.connexion.recv(1024)
                #ce qui tu as à faire avec cette commande
                self.connexion.send(b"la commande a bien été exécutée")#le rendu, ça va simplifier les choses de toujours faire ça, on peut évidemment mettre un autre message
     
    #pour l'établissement des connexions, j'imagine que tu sais comment faire
     
    thr_client1=Client(connexion_1)
    thr_client2=Client(connexion_2)
    thr_client3=Client(connexion_3)
    thr_client4=Client(connexion_4)
    thr_client1.start()
    thr_client2.start()
    thr_client3.start()
    thr_client4.start()
    Du côté du client, pas besoin de thread, juste un truc (je simplifie) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while True :
        connexion.send(input("Entrez la commande : ").encode())
        print(connexion.recv().decode())
    Voilà, ça devrait être bon.

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par hherve Voir le message
    Je suppose que le serveur doit utiliser les threads ? C'est une chose que je ne pige pas trop.
    Si je comprends le thread, c'est une manière de faire travailler mes connexions en parallèle (4 threads pour 4 ports) avec mon prog principal qui:
    1: surveille si quelque chose est arrivé d'un socket
    2: execute les ordres
    Sans perturber/retarder ce qu'il peut faire éventuellement d'autre.
    C'est bien cela ?
    Le serveur ne doit pas nécessairement utiliser les threads et les serveurs normaux évitent de les utiliser.
    Un serveur "normal" devant être capable de gérer un maximum de client, il devra utiliser un minimum de ressources ce qui est incompatible avec 1 client = 1 thread.

    Si vous avez 4 clients "au plus", utiliser 1 thread par client sera une simplification intéressante de votre code.

    Je peux récupérer facilement sous forme de string par exemple, chaque réception ?
    Vous utiliserez à priori TCP/IP.
    client et serveur vont s'échanger des streams de bytes.
    En Python, bytes et str sont de nature différentes.

    Maintenant si plusieurs ordres arrivent en même temps de mes différents clients que se passe-t-il ?
    Vais-je en zapper ?
    Risquent-ils d'être altérés ?
    Je précise que chaque client envoie beaucoup d'ordres. Avec la latence d'un réseau cela peut être de l'ordre d'un ordre toutes les 100mSec, et que chaque client n'est forcément pas synchrone, cela peut faire beaucoup de choses à traiter.
    TCP/IP vous garantit que les bytes écrits seront acheminés et reçus dans l'ordre. S'il y a un problème client et serveur çà va remonter une erreur que le code devra gérer.


    Voilà, c'est pas quelque chose de commun semble-t-il puisque je n'ai pas trouvé de bout de codes qui y ressemblerait. Enfin je dis cela, c'est surtout, parce que je ne sais par quel exemple commencer, étudier, dégrossir et poser des questions pour apprendre, comprendre et me corriger. (et m'en souvenir, car j'ai ma ram perso qui oublie vite )
    Je vous recommande la lecture et la pratique d'un tuto.
    Nous faisons ici beaucoup de publicité pour le Swinnen.
    Si vous voulez voir à quoi ressemble ce que vous voulez faire, vous pouvez lire le ch20.
    Si c'est "indigeste", c'est probablement qu'il vous faudra lire les chapitres précédents.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je me suis un peu amusé avec ce genre de serveur il y a quelques années, et j'en ai gardé quelques codes très simples ici: http://python.jpvweb.com/mesrecettes...eur_tcp_stream.

    Ils fonctionnent avec TCP/IP, mais ce n'est pas du web: le client est un programme spécifique, pas un navigateur.

    Il y a en particulier 2 serveurs "asynchrones", l'un utilisant les threads et l'autre les processus (chaque nouvelle requête est traitée sans attendre que la requête précédente soit terminée)

    C'est du Python 2, mais ça devrait pouvoir se convertir facilement en Python 3.

    Je viens de vérifier: ça continue à fonctionner (ça fait du calcul algébrique). Mais je n'ai jamais sollicité ces serveurs "à fond", et si tu les utilises, ça m'intéresse de savoir ce qui se passe alors.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    C'est du Python 2, mais ça devrait pouvoir se convertir facilement en Python 3.

    Je viens de vérifier: ça continue à fonctionner (ça fait du calcul algébrique). Mais je n'ai jamais sollicité ces serveurs "à fond", et si tu les utilises, ça m'intéresse de savoir ce qui se passe alors.
    Autant mentionner les exemples de la documentation Python du module socketserver.
    Ils sont à jour et bien plus complets que vos essais.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Janvier 2005
    Messages
    24
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : Technicien maintenance
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2005
    Messages : 24
    Par défaut
    Bonjour,

    merci pour vos réponses.

    J'ai donc pris un exemple du chapitre 20 de Mr Swinnen, et pas de chance (copié collé ) il fonctionne quand il veut, c'est à dire qu'il me refuse presque tout le temps la connexion....

    @ Tyrtamos, je vais aller voir votre site, mais il est sûr, comme dit W, qu'il faudrait que je comprenne bien comment fonctionne les socket, et que je vais aller chercher de la doc explicite là dessus.

    Je ne sais pas si c'est parce que je ne programmais jusqu'à maintenant qu'en BASIC sur µControlleurs, mais le python me désempare (j'ai pourtant lu en entier le bouquin du SDZ)

    Bien, j'ai quand même un petit prog récupéré qui tourne en threading sur 1 seul port (donc ça ne colle pas). Si ce prog peut servir de base, sans tout chambouller, j'en serais ravi.
    Il me faut limiter le nombre de connexion par port donc je dois passer le serversock.listen(5) à serversock.listen(1)
    mais pour avoir mes 4 connexions, quand tous mes clients veulent se connecter, c'est la ligne serversock.bind(ADDR) qui contient uniquement mon port défini plus haut qui pose pb. Je peux pas mettre 4 fois cette ligne avec 4 ports différents !
    Voilà le genre de choses qui me bloquent...

    PS: J'utilise PYTHON 2.7, et pour mes tests clients le freeware PUTTY


    Merci de vos idées
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
     
    from socket import *
    import thread
     
    BUFF = 25
    HOST = ''# must be input parameter @TODO
    PORT = 10002 # must be input parameter @TODO
    def response(key):
        return 'Server response: ' + key
     
    def handler(clientsock,addr):
        while 1:
            data = clientsock.recv(BUFF)
            if not data: break
            print repr(addr) + ' recv:' + repr(data)
            clientsock.send(response(data))
            print repr(addr) + ' sent:' + repr(response(data))
            if "close" == data.rstrip(): break # type 'close' on client console to close connection from the server side
     
        clientsock.close()
        print addr, "- closed connection" #log on console
     
    if __name__=='__main__':
        ADDR = (HOST, PORT)
        serversock = socket(AF_INET, SOCK_STREAM)
        serversock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        serversock.bind(ADDR)
        serversock.listen(5)
        while 1:
            print 'waiting for connection... listening on port', PORT
            clientsock, addr = serversock.accept()
            print '...connected from:', addr
            thread.start_new_thread(handler, (clientsock, addr))

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Prenez un truc qui (devrait) marche(r) sans threads:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    from socket import *
     
    BUFF = 25
    HOST = ''# must be input parameter @TODO
    PORT = 10002 # must be input parameter @TODO
    def response(key):
        return 'Server response: ' + key
     
    def handler(clientsock,addr):
        while 1:
            data = clientsock.recv(BUFF)
            if not data: break
            print repr(addr) + ' recv:' + repr(data)
            clientsock.send(response(data))
            print repr(addr) + ' sent:' + repr(response(data))
            if "close" == data.rstrip(): break # type 'close' on client console to close connection from the server side
     
        clientsock.close()
        print addr, "- closed connection" #log on console
     
    if __name__=='__main__':
        ADDR = (HOST, PORT)
        serversock = socket(AF_INET, SOCK_STREAM)
        serversock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        serversock.bind(ADDR)
        serversock.listen(1)
        clientsock, addr = serversock.accept()
        handler (clientsock, addr)
    Transformez le en fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    from socket import *
    from socket import *
     
    BUFF = 25
     
    def server(host, port):
     
        def response(key):
            return 'Server response: ' + key
     
        def handler(clientsock,addr):
            while 1:
                data = clientsock.recv(BUFF)
                if not data: break
                print repr(addr) + ' recv:' + repr(data)
                clientsock.send(response(data))
                print repr(addr) + ' sent:' + repr(response(data))
                if "close" == data.rstrip(): break # type 'close' on client console to close connection from the server side
     
            clientsock.close()
            print addr, "- closed connection" #log on console
     
        addr = (host, port)
        serversock = socket(AF_INET, SOCK_STREAM)
        serversock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        serversock.bind(addr)
        serversock.listen(1)
        clientsock, addr = serversock.accept()
        handler(clientsock, addr)
     
    if __name__=='__main__':
        HOST = ...
        PORT = ...
        server(HOST, PORT)
    Puis on associe un thread par port:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if __name__=='__main__':
        import threading
        HOST = ...
        PORTS = ...
        threads = []
        for port in PORTS:
             th = threading.thread(target=server, args=(HOST, port))
             th.start()
             threads.append(th)
        ... ici on attend que ca se termine...
    L'idée d'organisation est: un serveur qui fonctionne pour un port qu'on réplique sur les N port.
    Reste à rendre çà plus robuste: çà prend plus de temps que faire des cut&paste!
    Et vous n'etes pas encore rendu ;-)

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 4
    Dernier message: 04/03/2014, 03h42
  2. multi thread et port serie
    Par mich35 dans le forum C#
    Réponses: 4
    Dernier message: 03/07/2012, 09h33
  3. création d'un serveur multi-thread
    Par james23 dans le forum Multithreading
    Réponses: 9
    Dernier message: 30/03/2009, 18h11
  4. question article "Création d'un serveur multi-threads en C++"
    Par contremaitre dans le forum Threads & Processus
    Réponses: 2
    Dernier message: 20/06/2008, 13h01
  5. [BP7] Multi-cpu, multi-core, multi-thread et programme Pascal
    Par Transgarp dans le forum Turbo Pascal
    Réponses: 6
    Dernier message: 07/04/2008, 19h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo