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

Python Discussion :

Probleme d'optimisation serveur [Python 3.X]


Sujet :

Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut Probleme d'optimisation serveur
    Bonjours j'ai réaliser un programme qui permet au client de connaitre rapidement l'etat d'un reseau http://www.developpez.net/forums/d15...-notification/. Le soucis c'est que le serveur doit tenir informer plusieur dizaine de clients or 1client RAS, 2clients sa va, 3clients ça lag (interface serveur), 4clients le serveur freeze; on est loin de la dizaine je voudrais donc savoir comment résoudre ce soucis. (ce n'est pas le Pc j'ai un i7-4790k avec 16Go de ram).
    J'ai penser a reduire le nombre de thread mais je ne voie pas par quoi les remplacers, je me suis dit que ça pouvait venir des "while True" ?

    Serveur:
    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    import socket
    import threading
    from tkinter import *
     
    global Client_online, Etat_reseau
     
     
    def Etat_0():
        Etat_reseau.set("Bon")
        print("Update", Etat_reseau.get())
     
    def Etat_1():
        Etat_reseau.set("Moyen")
        print("Update", Etat_reseau.get())
     
    def Etat_2():
        Etat_reseau.set("Mauvais")
        print("Update", Etat_reseau.get())
     
     
    class ClientThread(threading.Thread):
     
        def __init__(self, ip, port, clientsocket, Etat_reseau):
     
            threading.Thread.__init__(self)
            self.ip = ip
            self.port = port
            self.clientsocket = clientsocket
            self.Etat_reseau_client = StringVar()
            self.Etat_reseau_client.set("none")
            self.Etat_reseau = Etat_reseau.get()
     
            print("[+] Nouveau thread pour %s %s" % (self.ip, self.port, ))
     
            Client_online.append(ip)
     
        def run(self):
     
            nb_send = 0
            paquet = ""
     
            #print("Etat_reseau_client ",self.Etat_reseau_client)
     
            print("ConnecTion de %s %s" % (self.ip, self.port, ))
            print("HH", Etat_reseau.get(), self.Etat_reseau_client.get())
     
     
            while True: #Envoie l'etat seulement lors d'une update ou du premier cycle(le client ne connais pas l'etat)
     
                #print("tt", Etat_reseau.get(), self.Etat_reseau_client.get())
     
                if Etat_reseau.get() != self.Etat_reseau_client.get() or nb_send == 0:
     
                    nb_send = nb_send + 1
     
                    #print('ici')
     
                    a = Etat_reseau.get()
                    self.Etat_reseau_client.set(a)
                    paquet = str(str(self.Etat_reseau_client.get()) + chr(0)).encode('latin-1')
                    self.clientsocket.send(paquet)
     
                    print("nb_send", nb_send, "ET", Etat_reseau.get(), "ETC", self.Etat_reseau_client.get())
     
     
     
     
    class Ecoute(threading.Thread): #Thread d'ecoute qui permet au client de ce connecter
     
        def __init__(self, ip, port, clientsocket, Etat_reseau):
     
            threading.Thread.__init__(self)
     
        def run(self):
     
            while True:
                tcpsock.listen(1000)#Nb de client pouvant etre connecter au serveur
                print( " En écoute...")
                (clientsocket, (ip, port)) = tcpsock.accept()
                newthread = ClientThread(ip, port, clientsocket, Etat_reseau)
                newthread.start()
     
     
     
    Client_online = []
    ip = ""
    port = 0
    clientsocket = ""
     
     
     
    fenetre_choix = Tk()
    fenetre_choix.title("Panel d'administration")
    fenetre_choix.configure(bg = "#00B3D7")
     
    button_heber = Button(fenetre_choix, text = "Aucun probleme connue",font="arial 12 bold",command=Etat_0, bg = "white", relief=FLAT)
    button_rej = Button(fenetre_choix, text = "Perturbation connue sur le reseau",font="arial 12 bold", command=Etat_1, bg = "white", relief=FLAT)
    button_ia = Button(fenetre_choix, text = "Reseau indisponible",font="arial 12 bold",command=Etat_2, bg = "white", relief=FLAT)
    taille_x_l = Label(fenetre_choix, bg = "#00B3D7")
    taille_y_b = Label(fenetre_choix, bg = "#00B3D7")
    info_ip = Label(fenetre_choix, text = "Quelle est l'etat du reseau ?", bg = "#00B3D7")
     
    taille_x_l.pack(side=TOP,padx=380,pady=20)
    button_heber.pack(side=TOP,padx=50,pady=10)
    button_rej.pack(side=TOP,padx=50,pady=10)
    button_ia.pack(side=TOP,padx=50,pady=10)
    taille_y_b.pack(side=TOP,pady=80)
    info_ip.pack(side=BOTTOM)
     
     
     
    Etat_reseau = StringVar()
    Etat_reseau.set("Bon") #0: bon 1:moyen 2:mauvais
     
     
    tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    tcpsock.bind(("",50000))
     
     
    newthread_Ecoute = Ecoute(ip, port, clientsocket, Etat_reseau)
    newthread_Ecoute.start()
     
     
    fenetre_choix.mainloop()
    Client:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import socket
     
    connexion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connexion.connect(("localhost", 50000))
     
     
    while True:
            try:
                msgServ = connexion.recv(1024) # on recoit le message
     
                print("message du Serveur", msgServ.decode('latin-1'))
                #paquethandler(msgClient) # on le gére
            except:
                pass
    Merci de votre aide

    PS: Je suis un noob

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par CraZy_U2P Voir le message
    Bonjours j'ai réaliser un programme qui permet au client de connaitre rapidement l'etat d'un reseau http://www.developpez.net/forums/d15...-notification/.
    "localhost" c'est un pseudo réseau qui passe par la mémoire du serveur. Les temps de réponses sont excellents mais pas du tout réalistes. De fait, si le serveur se contente de créer une thread par client qui vont toutes expédier un message "ca va bien" dès que possible, en augmentant le nombre de threads vous aller assez rapidement saturer la bande passante mémoire de la machine et/ou la ressource CPU disponible (limité à environ a 1 CPU avec les threads Python).

    Pourquoi ne pas faire une pause (time.sleep(n)) avant d'expédier le message suivant?
    note: et faire time.sleep (ou attendre) étant presque le seul intérêt des threads...

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

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut
    Pourquoi ne pas faire une pause (time.sleep(n)) avant d'expédier le message suivant?
    Je ne comprend pas vraiment ton idée, en gros arreter ClientThread tant qu'il n'y a pas d'update de l'etat reseau? comment faire sans passer par un while avec un if ?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par CraZy_U2P Voir le message
    Je ne comprend pas vraiment ton idée, en gros arreter ClientThread tant qu'il n'y a pas d'update de l'etat reseau? comment faire sans passer par un while avec un if ?
    Relisez votre code.
    Le client fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
          while True:
                si qqc à changé alors:
                      ....
    est-ce que qqc change souvent? Non.
    Donc dans la plupart des cas, votre boucle se réduit à:
    Et une boucle qui ne fait rien reste quand même une boucle.
    Quel est l'intérêt de tester la condition toutes les nano-secondes?
    Vous pourriez "ralentir":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
          while True:
                si qqc à changé alors:
                      ....
                time.sleep(0.1)
    Vous pourriez aussi "changer" de design.
    L’état du réseau change. On doit avertir les clients. Plutôt qu'avoir un thread par client, vous pourriez avoir un seul thread qui s'occupe de mettre à jour l'ensemble des clients lorsque...
    Comment faire pour faire qu'une tache asynchrone "attende" qu'il y ait quelque chose à faire plutôt que de "boucler" pour voir si? Vous avez dans le module threadings des objets appelés Event qui sont fait pour çà. Vous avez aussi le module queue qui permet de faire ce genre de chose.

    Un autre design serait d'éviter côté serveur à garder ouvertes les connections indéfiniment: chaque client peut se connecter au serveur, récupérer l'état du réseau s'il le peut, et on ferme la connexion. Et on recommence toutes les x millisecondes.

    Après si vous voulez vous lancez dans une programmation assez difficile sans avoir pris le temps d'avoir un peu lu des tutos sur le sujet et un peu compris les difficultés à résoudre et les techniques à mettre en œuvre, vous n'êtes pas arrivé au bout de vos peines (et on ne peut pas apprendre à votre place).

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

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut
    Merci beaucoup tu m'a donner pas mal d'idée. J'ai crue comprendre sur d'autre forum/pages sur le threading qu'un thread fonctionne comme un programme, quand il arrive au bout il s’arrête, est ce bien ça ou suis je a coter de la plaque ? car dans ce cas j'ai penser a toujours faire un thread par client mais il ce résume a connecter le client, envoyer l'info, fermer la connexion ce qui dure que quelque centième de seconde et allège le programme. Le client va quand a lui ce reconnecter toutes les x minutes pour s'actualiser. Cela ferais 2 threads permanent, interface et ecoute plus un nombre indefinie de thread qui eut n'existerons que le temps de quelque ligne. Est ce que ça vous parais plausible?

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par CraZy_U2P Voir le message
    Cela ferais 2 threads permanent, interface et ecoute plus un nombre indefinie de thread qui eut n'existerons que le temps de quelque ligne. Est ce que ça vous parais plausible?
    Si la durée de vie d'un thread se réduit à un pou-ième, pourquoi la créer? Autant faire le boulot "sans".
    De toutes façons comme vous débutez, faire tomber le truc en marche serait "assez bien".

    Plus tard, vous pourriez essayer de faire fonctionner le tout sans utiliser de threads.
    Juste pour le "fun" de pouvoir comparer ce que les threads simplifient et compliquent.

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

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut
    Je ne voie pas comment faire sans creer ce 3eme thread meme pour quelque ligne car si l'interface est en pose elle n'est plus interactive et si l'ecoute est en pose ça pourrais faire louper des clients, il me faut la boucle principale et 2thread a coter. Sur mes differents projet je ne m'etait encore jamais confronter a un probleme d'optimisation/performance... c'est compliquer

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par CraZy_U2P Voir le message
    Je ne voie pas comment faire sans creer ce 3eme thread meme pour quelque ligne car si l'interface est en pose elle n'est plus interactive et si l'ecoute est en pose ça pourrais faire louper des clients, il me faut la boucle principale et 2thread a coter. Sur mes differents projet je ne m'etait encore jamais confronter a un probleme d'optimisation/performance... c'est compliquer
    Dommage car, vous pourriez alors coder le serveur assez simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
     
    etat_reseau = 'unknown'
     
    def server():
        sd = socket(AF_INET, SOCK_STREAM)
        sd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        sd.bind(("",50000))
        sd.listen(10)
        while True:
            (cs, (ip, port)) = sd.accept()    
            print("[+] Nouveau client %s %s" % (ip, port))
            cs.send(etat_reseau.encode())
            cs.close()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut
    XD ça c'est de l'optimisation tu viens de résumer presque 2 semaines de boulot (dont 3 jours pour trouver une erreur de syntaxe) ^^
    Mais par contre le listen, tu ne doit pas "rester" dessus pour ensuite pouvoir accepter les connexions?

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par CraZy_U2P Voir le message
    XD ça c'est de l'optimisation tu viens de résumer presque 2 semaines de boulot (dont 3 jours pour trouver une erreur de syntaxe) ^^
    Mais par contre le listen, tu ne doit pas "rester" dessus pour ensuite pouvoir accepter les connexions?
    C'est plutôt "accept" qui, comme son nom l'indique, "acceptera les connexions".

    "optimiser", c'est améliorer les performances d'une solution qui fonctionne.
    Ici, je me suis contenté de repenser la solution: plutôt qu'avoir un serveur qui "pousse" une information, ce sont les clients qui "tirent". Ce qui permet au serveur d'être "stateless" plutôt que "statefull". Et au final, on a beaucoup moins de lignes de code à écrire. Mais ce n'est que redécouvrir quelques uns de principes d'un serveur HTTP.

    Mettre au point un code est généralement très chronophage. C'est une des raisons qui faire qu'on doit réfléchir avant de se jeter sur le clavier, pour que ce soit le plus simple possible (et faire le boulot qu'on en attend).

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

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut Des bugs et encore des bugs, j'en est a vendre si vous voulez...
    Bonsoir a tous
    Le serveur est optimiser mais bugger... 1client ce connecte ça va, 2 clients le premier part en boucle sur mon print(msgServ) alors qu'il ne reçoit en théorie aucun message...

    Le serveur:

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
    import threading
    from tkinter import *
     
    """
     a = 0
            print(Client_online)
            for IP in Client_online:
                a = a+1
                PORT = Client_online.get(IP)
                print(a, IP, PORT)
                paquet = str(str(Etat_reseau.get()) + chr(0)).encode('latin-1')
    """
     
    def Update(): #Envoie l'etat reseau aux client apres avoir clic sur l'interface seulement si l'etat change
        global cs, Etat_Client
     
        print("11 ",Etat_Client, Etat_reseau.get())
        if Etat_Client != Etat_reseau:
     
            info_action.config(text="Action en cours: Actualisation des Clients en cours")
     
            cs.send(str(Etat_reseau.get()).encode())
     
        info_action.config(text="Action en cours: Aucune")
        Etat_Client = Etat_reseau.get()
        print("22 ",Etat_Client, Etat_reseau.get())
     
    def Etat_0():
     
        Etat_reseau.set("Bon")
        info_etat.config(text="Etat du reseau: Aucun probleme connue")
        print("Update", Etat_reseau.get())
        Update()
     
    def Etat_1():
     
        Etat_reseau.set("Moyen")
        info_etat.config(text="Etat du reseau: Presence de ralentissement sur le reseau")
        print("Update", Etat_reseau.get())
        Update()
     
    def Etat_2():
     
        Etat_reseau.set("Mauvais")
        info_etat.config(text="Etat du reseau: Reseau indisponible")
        print("Update", Etat_reseau.get())
        Update()
     
    def Serveur():
     
        global Etat_Client, cs
     
        SocketClient = socket(AF_INET, SOCK_STREAM)
        SocketClient.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        SocketClient.bind(("",50000))
        SocketClient.listen(10)
        print("Ecoute...")
        Etat_Client = Etat_reseau.get()
     
        while True: #Connecte les clients et leur indique l'etat reseau
     
            (cs, (ip, port)) = SocketClient.accept()    
            print("[+] Nouveau client %s %s" % (ip, port))
            Client_online[ip] = port
            cs.send(str(Etat_reseau.get()).encode())
            print("Ecoute")
     
     
     
    class Ecoute(threading.Thread):
     
        def __init__(self, ip, port, Etat_reseau):
     
            threading.Thread.__init__(self)
     
        def run(self):
     
            Serveur()
     
     
    Client_online = {}
    ip = ""
    port = 0
     
     
    fenetre_choix = Tk()
    fenetre_choix.title("Panel d'administration")
    fenetre_choix.configure(bg = "#00B3D7")
     
    Etat_reseau = StringVar()
    Etat_reseau.set("Bon") #0: bon 1:moyen 2:mauvais
     
    info_etat = Label(fenetre_choix, text = "Etat du reseau: Aucun probleme connue" , bg = "#00B3D7")
    info_action = Label(fenetre_choix, text = "Action en cours: Aucune", bg = "#00B3D7")
    button_bon = Button(fenetre_choix, text = "Aucun probleme connue",font="arial 12 bold",command=Etat_0, bg = "#33FF00", relief=FLAT)
    button_moy = Button(fenetre_choix, text = "Presence de ralentissement sur le reseau",font="arial 12 bold", command=Etat_1, bg = "#FFFF00", relief=FLAT)
    button_mau = Button(fenetre_choix, text = "Reseau indisponible",font="arial 12 bold",command=Etat_2, bg = "#CC0000", relief=FLAT)
    taille_x_l = Label(fenetre_choix, bg = "#00B3D7")
    taille_y_b = Label(fenetre_choix, bg = "#00B3D7")
    info_ip = Label(fenetre_choix, text = "Quelle est l'etat du reseau ?", bg = "#00B3D7")
     
    info_etat.pack(side=TOP)
    info_action.pack(side=TOP,pady=20)
    taille_x_l.pack(side=TOP,padx=380)
    button_bon.pack(side=TOP,padx=50,pady=10)
    button_moy.pack(side=TOP,padx=50,pady=10)
    button_mau.pack(side=TOP,padx=50,pady=10)
    taille_y_b.pack(side=TOP,pady=40)
    info_ip.pack(side=BOTTOM)
     
     
    newthread_Ecoute = Ecoute(ip, port, Etat_reseau)
    newthread_Ecoute.start()
     
    fenetre_choix.mainloop()
    Client avec interface (attention 2 clients avec interface lancer en meme temps transforme votre pc en stroboscope ! En plus g un "bug" l'icone ne change pas de couleur en fonction du message du serveur cf Update() ) :


    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    import socket
    import sys
    from PyQt5 import (QtWidgets, QtGui, QtCore)
    import threading
     
    global qicone, icone
     
    icone = "vert.png"
     
    programme = "Etat du reseau Falcon"
    bulle = programme
     
     
     
    class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
     
     
        def __init__(self, app, qicone, bul="", parent=None):
            super().__init__(qicone, parent)
     
            self.app = app
            self.parent = parent
     
     
     
     
            # ajoute une bulle d'information quand la souris est sur l'icône tray
            if bul != "":
                self.setToolTip(bul)
     
            # initialise le menu
            self.initmenu()
     
     
        def initmenu(self):
            """initialise le popupmenu qui apparaitra au clic droit sur l'icône 
               on peut, bien sûr, ajouter d'autres items, 
               par exemple le "à propos" ou des items de configuration
            """
            # crée le menu
            menu = QtWidgets.QMenu(self.parent)
     
            # ferme la fenêtre et quitte le programme:
            # l'icône de l'item "Quitter" du menu sera une simple croix rouge
            quitterIcon = QtGui.QIcon.fromTheme("application-exit", QtGui.QIcon("icone_quitter.png"))
            quitterAction = QtWidgets.QAction(quitterIcon, '&Quitter', self)
            quitterAction.triggered.connect(self.quitter)
            menu.addAction(quitterAction)
     
            self.setContextMenu(menu)
     
     
        @QtCore.pyqtSlot("QObject")
     
        def affichefenetre(self, raison=None):
     
            pass
     
     
        @QtCore.pyqtSlot()
        def quitter(self):
            """permet de quitter: ferme le programme ainsi que le systemtray
            """
            reponse = QtWidgets.QMessageBox.question(None,
                              "Confirmez!",
                              "Voulez-vous vraiment quitter?",
                              QtWidgets.QMessageBox.Yes,
                              QtWidgets.QMessageBox.No)
            if reponse == QtWidgets.QMessageBox.Yes:
                # ferme la fenêtre si elle est encore ouverte
                connexion.close()
                self.app.quit()
     
        def Update_etat(self):
     
            print("ici")
     
            if msgServ.decode('latin-1') == "Bon":
     
                print("vert")
                icone = "vert.png"
                qicone = QTGui.QIcon.swap("vert.png") 
     
     
            elif msgServ.decode('latin-1') == "Moyen":
     
                print("jaune")
                icone = "jaune.png"
                qicone = QTGui.QIcon.swap("jaune.png") 
     
     
            elif msgServ.decode('latin-1') == "Mauvais":
     
                print("rouge")
                icone = "rouge.png"
                qicone = QTGui.QIcon.swap("rouge.png")
     
     
     
    class Connexion(threading.Thread):
     
        def __init__(self):
     
            threading.Thread.__init__(self)
     
        def run(self):
     
            connexion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            connexion.connect(("localhost", 50000))
     
     
            while True:
                    try:
                        msgServ = connexion.recv(1024) # on recoit le message
     
                        print("message du Serveur", msgServ.decode('latin-1'))
                        #paquethandler(msgClient) # on le gére
                        if trayIcon.supportsMessages():
                            trayIcon.showMessage(programme, # programme est une variable globale
                                 "Actualisation de l'etat du reseau Falcon",
                                 QtWidgets.QSystemTrayIcon.Information,
                                 1000)  # temps d'affichage en millisecondes
                        Update_etat()
                    except:
                        pass
     
     
    newthread = Connexion()
    newthread.start()
     
    if __name__ == '__main__':
     
     
        app = QtWidgets.QApplication(sys.argv)
     
     
        # définition du style (à adapter selon l'OS)
        if sys.platform=="win32":
            app.setStyle(QtWidgets.QStyleFactory.create("Fusion"))
        elif sys.platform=="linux":
            app.setStyle(QtWidgets.QStyleFactory.create("gtk"))
        elif sys.platform=="darwin":    
            app.setStyle(QtWidgets.QStyleFactory.create("macintosh"))
     
     
        qicone = QtGui.QIcon(icone)  # icone afficher par defaut
        app.setWindowIcon(qicone)
     
        trayIcon = SystemTrayIcon(app, qicone, bulle)  # bulle est une variable globale
        trayIcon.show()
     
        sys.exit(app.exec_())
    Client Console (aucun bug pour une fois) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    import socket
    connexion = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connexion.connect(("localhost", 50000))
    while True:
        try:
            msgServ = connexion.recv(1024) # on recoit le message   
            print("message du Serveur", msgServ.decode('latin-1'))
        except:
            pass





    Edit: Voila les icônes pour le client avec interface, je les avait oublier Nom : rouge.png
Affichages : 210
Taille : 9,6 KoNom : vert.png
Affichages : 187
Taille : 8,1 KoNom : icone_quitter.png
Affichages : 198
Taille : 1,3 KoNom : jaune.png
Affichages : 190
Taille : 7,0 Ko (a mettre au même niveau que le .py)

  12. #12
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Si vous ne testez pas que les différents composants de votre code "fonctionnent" tel qu'attendu, çà ne fonctionnera pas.
    Relisez votre code, côté serveur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        while True: #Connecte les clients et leur indique l'etat reseau
     
            (cs, (ip, port)) = SocketClient.accept()    
            print("[+] Nouveau client %s %s" % (ip, port))
            Client_online[ip] = port
            cs.send(str(Etat_reseau.get()).encode())
            print("Ecoute")
    A chaque itération, on change de client (à chaque retour d'accept) et le déreférencement de "cs" provoque la fermeture de la connexion réseau (précédente).
    Côté client:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            while True:
                    try:
                        msgServ = connexion.recv(1024) # on recoit le message
                        ...
    Le réseau va d'abord remonter les bytes expédiés par le serveur, puis autant autant de chaînes vides que d'appels à .recv qui signalent que la connexion a été fermée par le serveur: si vous ne testez pas cela, çà boucle forever.
    Ceci dit, à part constater que le code du client n'est pas cohérent avec le protocole supporté par le serveur...

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

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    A chaque itération, on change de client (à chaque retour d'accept) et le déréférencement de "cs" provoque la fermeture de la connexion réseau (précédente).
    D'accord mais si je fais quelque chose du genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    (cs+n_connection).send(str(Etat_reseau.get()).encode())
    n_connection = n_connection+1
    Pour avoir cs1, cs2.... je n'y arrive pas et j'ai crue comprendre que c'est impossible. Je veux bien une solution ? est ce que sendto(data,(ip,port)) necessite cs. devant ? ça pourrais être une solution.

    De plus je ne comprend pas pourquoi ce client ne correspond pas a ce type de serveur.


    Merci d'avance pour ta réponse.

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par CraZy_U2P Voir le message
    De plus je ne comprend pas pourquoi ce client ne correspond pas a ce type de serveur
    Ben, si c'était cohérent, çà fonctionnerait, non?

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

  15. #15
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut
    que repondre a ça XD

    Mais tu n'aurais pas une idee? actuellement j'ajoute chaque ip et son port dans un dico afin d'utiliser sendto dans un for mais le probleme c'est que la commande c cs.sendto(...) donc ça fonctionne pas a cause du soucis que tu a relever, et je ne vois pas comment le résoudre :/

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par CraZy_U2P Voir le message
    mais le probleme c'est que la commande c cs.sendto(...) donc ça fonctionne pas a cause du soucis que tu a relever, et je ne vois pas comment le résoudre :/
    Résoudre un problème, c'est commencer par essayer de le comprendre.
    Imaginons le serveur:

    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
    from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
     
    etat_reseau = 'unknown'
     
    def server():
        sd = socket(AF_INET, SOCK_STREAM)
        sd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        sd.bind(("",50000))
        sd.listen(10)
        while True:
            (cs, (ip, port)) = sd.accept()    
            print("[+] Nouveau client %s %s" % (ip, port))
            cs.send(etat_reseau.encode())
            cs.close() # on peut mettre cela en commentaire et faire faire le boulot par le garbage collector...
     
    server()
    En face, on met un client zarbi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
     
    sd = socket(AF_INET, SOCK_STREAM)
    sd.connect(('localhost',50000))
    while True:
        m = sd.recv(512)
        print (len(m))
        if m:
            print (m.decode())
        n = input()
    Il est "zarbi" parce qu'il ne sort jamais du "while True" et se contente d'afficher la longueur du message reçu et son contenu si non nul... votre client fait-il plus que çà?

    Et s'il ne fait pas plus comment espérer (en fait coder...) qu'il fasse le boulot attendu?

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

  17. #17
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Résoudre un problème, c'est commencer par essayer de le comprendre.
    Pour moi j'ai comprit le problème, c'est ma manière de gérer les connexion entrante qui m’empêche de conserver plusieurs client connecter en même temps "vue que cs est une variable global" (sur mon ancien serv cs été une variable local a chaque thread (1thread par client)). Et je ne voie pas comment conserver ces clients connecter autrement que par l'ancienne méthode.

    Ou alors le client ce connecte récupère l'info ce déconnecte et ce met en écoute, a chaque update le serveur va ce connecter a chaque client un part un envoie l'info puit ce deconnecter. Cette methode est elle envisageable sans avoir a ouvrir les port du routeur de chaque client en cas de connexion par internet et non local?

  18. #18
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par CraZy_U2P Voir le message
    Pour moi j'ai comprit le problème, c'est ma manière de gérer les connexion entrante qui m’empêche de conserver plusieurs client connecter en même temps "vue que cs est une variable global" (sur mon ancien serv cs été une variable local a chaque thread (1thread par client)). Et je ne voie pas comment conserver ces clients connecter autrement que par l'ancienne méthode.
    Soit les clients vont récupérer à intervalles régulier etat_reseau renvoyé par le serveur et c'est relativement simple à coder:
    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
    from socket import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
    import time
     
    def get_etat_reseau():
        sd = socket(AF_INET, SOCK_STREAM)
        sd.connect(('localhost',50000))
        data = []
        while True:
            m = sd.recv(512)
            if not m:
                break
            data.append(m.decode())
        return ''.join(data)
     
    while True:
        print (get_etat_reseau())
        time.sleep(0.1)
    Et dans ce cas, le serveur n'a pas à gérer de clients.

    Soit c'est le serveur qui expédie l'information à tous les clients qu'il connaît... mais c'est beaucoup plus de lignes de code et de temps passé à la mise au point. En outre, cela suppose que la connexion entre client et serveur soit "permanente": ce qui n'est jamais assuré! Il faut donc penser (et coder) à la détection d'incidents et à la mise en place de "reprises".

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

  19. #19
    Nouveau membre du Club
    Homme Profil pro
    Etudiant
    Inscrit en
    Mars 2015
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Etudiant

    Informations forums :
    Inscription : Mars 2015
    Messages : 54
    Points : 28
    Points
    28
    Par défaut
    lors de la déconnexion d'un client j'ai une erreur "non fatal" coter serveur et le client par lui en boucle sur le print de message vide, coter client on peut donc très facilement détecter une déconnexion(avec l'exemple que tu ma donner dans un de tes poste précédent), coter serveur je ne sais pas encore comment mais l'erreur doit être exploitable.
    Apres ce programme que je dois avoir fini pour demain matin est un prototype et pas une version final il me faut un serveur avec au moins 2 clients de connecter au serveur, qui s'actualise en direct(j'ai toujours l'ancien serveur non opti dans le pire des cas).
    J'ai conscience depuis le départ que l'actualisation en direct est plus dur (pas a ce point certes) mais l'actualisation tout les x temps est soit trop lourde(il y aura 800 client a terme j'ai enfin une idée du chiffre exacte), soit pas propre(avec le serveur actuelle on pourrais faire spam le client le serveur de connexion), soit trop lentes. après je sais que c'est trois problèmes on une solution mais bon je trouve quand même l'actualisation en direct plus adapter.

    Avec le serveur en thread j'avais les client en parallèle, il n'y pas de solution pour les gérer en série?

    Edit: je suis entrain de refaire le serveur pour ton client qui ma l'air opti contrairement a mon premier client du même genre

  20. #20
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,


    J'ai conscience depuis le départ que l'actualisation en direct est plus dur (pas a ce point certes) mais l'actualisation tout les x temps est soit trop lourde(il y aura 800 client a terme j'ai enfin une idée du chiffre exacte), soit pas propre(avec le serveur actuelle on pourrais faire spam le client le serveur de connexion)
    Quelque soit le protocole (push ou pull), il sera toujours possible de rendre le service indisponible via des floods de requêtes de connexion. La seule solution serait côté parefeu et detection d'intrusion mais ce sont des composants logiciels et physiques à ajouter entre le serveur et internet.

    Après n'oubliez pas que si vous devez déployer vos clients sur 800 postes de travail, le moindre bug c'est "comprendre ce qu'il s'est passé", corriger, tester et déployer la correction.
    Au plus votre code sera compliqué et au plus la probabilité de "bug" sera importante.
    Et vous n'avez même pas mis en place un service de logging pour comprendre ce qui a bien pu se passer...

    Comme vous débutez, vous êtes loin d'être à l'aise avec ce genre de code (sinon vous ne demanderiez pas de l'aide ici).... et vous n'avez aucune idée des difficultés à résoudre et encore moins du "comment".

    A vous de voir...

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

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Compiler du java en natif & Optimisation serveur socket
    Par Skreo dans le forum API standards et tierces
    Réponses: 32
    Dernier message: 09/07/2006, 16h31
  2. [VBA-E]Probleme d'optimisation
    Par sk8bcn dans le forum Macros et VBA Excel
    Réponses: 18
    Dernier message: 30/05/2006, 20h14
  3. Problèmes sur le serveur forum ?
    Par Baptiste Wicht dans le forum Mode d'emploi & aide aux nouveaux
    Réponses: 19
    Dernier message: 24/04/2006, 16h20
  4. [EasyPHP] probleme include d'serveur distant au serveur local EasyPHP?
    Par jeff1985 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 8
    Dernier message: 04/04/2006, 11h14
  5. Problemes de connexion Serveur Interbase
    Par OasisMan dans le forum Bases de données
    Réponses: 1
    Dernier message: 08/03/2005, 08h39

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