Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problèmes thread Tchat Console

affichage décalé

Sujet résolu
    23 septembre 2017 à 14:24:43

    Bonjour à tous,

    Je suis en train de suivre le tuto de Vincent Le Goff sur le langage python.

    J'ai fini la partie Réseau et la partie sur les Threads, j'ai donc essayer de finir le petit

    exemple sur le Tchat montré dans la partie Réseau.

    J'ai essayé d'y inclure les Threads pour pouvoir mettre la réception et l'envoie de message coté client

    de façon parallèle.

    Le problème est que au niveau de l'affichage ça bugg pas mal, quand j'envoie le message,

    il y a un fort décalage à la réception.

    Je pense que le serveur fonctionne bien mais que c'est le client qui s’emmêle les pédales.

    Je vous montre le code peut-être que la réponse est toutes bête ... :-°

    serveur.py

    #! /usr/bin/python3
    # -*-coding:UTF-8*-
    
    # --- SERVEUR ---
    
    import socket
    import select
    
    hote = ''
    port = 12800
    
    connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    connexion_principale.bind((hote, port))
    connexion_principale.listen(5)
    print("Le serveur écoute à présent sur le port {}".format(port))
    
    serveur_lance = True
    clients_connectes = []
    while True:
        # On va vérifier que de nouveaux clients ne demandent pas à se connecter
        # Pour cela, on écoute la connexion_principale en lecture
        # On attend maximum 50ms
        connexions_demandees, wlist, xlist = select.select([connexion_principale],
                                                           [], [], 0.05)
    
        for connexion in connexions_demandees:
            connexion_avec_client, infos_connexion = connexion.accept()
            # On ajoute le socket connecté à la liste des clients
            clients_connectes.append(connexion_avec_client)
    
        # Maintenant, on écoute la liste des clients connectés
        # Les clients renvoyés par select sont ceux devant être lus (recv)
        # On attend là encore 50ms maximum
        # On enferme l'appel à select.select dans un bloc try
        # En effet, si la liste de clients connectés est vide, une exception
        # Peut être levée
        clients_a_lire = []
        try:
            clients_a_lire, wlist, xlist = select.select(clients_connectes,
                                                         [], [], 0.05)
        except select.error:
            pass
        else:
            # On parcourt la liste des clients à lire
            for client in clients_a_lire:
                # Client est de type socket
                msg_recu = client.recv(1024)
                # Peut planter si le message contient des caractères spéciaux
                print("Reçu {}".format(msg_recu.decode()))
    
                for cl in clients_connectes:
                    cl.send(msg_recu)
                    # print("Voici les clients connectés : {}".format(cl))
                # On verifi que le message
                # n'est pas 'fin'
                # Sinon on ferme le serveur
                # fin = msg_recu.decode().split(':')[1].strip()
    
                # if fin == "fin":
                # serveur_lance = False
    
                # On renvoie le message à tous les
                # client sauf à celui qui l'a envoyé
    
    print("Fermeture des connexions")
    for client in clients_connectes:
        client.close()
    
    connexion_principale.close()
    

    client.py

    #! /usr/bin/python3
    # -*-coding:UTF-8*-
    
    # --- CLIENT ---
    
    import socket
    import json
    from threading import Thread
    from urllib.request import urlopen
    
    
    hote = 'localhost'
    port = 12800
    
    
    class Envoyer(Thread):
    
        """ Thread chargé simplement d'envoyer
            les messages au serveur """
    
        def __init__(self, connexion_avec_serveur, msg_envoyer):
            Thread.__init__(self)
            self.msg_envoyer = msg_envoyer
            self.connexion_avec_serveur = connexion_avec_serveur
    
        def run(self):
            """ Code à exécuter pendant l'exécution du thread. """
            self.msg_envoyer = input("> ")
            self.msg_envoyer = "{} : {}".format(ip, self.msg_envoyer)
            # On envoie le message
            self.connexion_avec_serveur.send(self.msg_envoyer.encode())
    
    
    class Recu(Thread):
    
        """ Thread chargé simplement d'afficher
            les message qui viennent du serveur """
    
        def __init__(self, connexion_avec_serveur, msg_envoyer):
            Thread.__init__(self)
            self.msg_envoyer = msg_envoyer
            self.connexion_avec_serveur = connexion_avec_serveur
    
        def run(self):
            """ Code à exécuter pendant l'exécution du thread. """
            self.msg_recu = self.connexion_avec_serveur.recv(1024)
            print(self.msg_recu.decode())
    
    
    hote = 'localhost'
    port = 12800
    # Initialisation de la socket
    connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    # Initialisation de la connexion
    # avec l'adresse du serveur et son
    # port d'écoute
    connexion_avec_serveur.connect((hote, port))
    print("Connexion établie avec le serveur sur le port {}".format(port))
    
    msg_envoyer = b""
    
    # Recherche de l'adresse IP de l'utilisateur
    r = urlopen('http://httpbin.org/ip').read()
    ip = json.loads(r.decode())['origin']
    
    print("Votre adresse IP est {}".format(ip))
    
    
    while msg_envoyer != "{} : fin".format(ip):
        thread_envoyer = Envoyer(connexion_avec_serveur, msg_envoyer)
        thread_recu = Recu(connexion_avec_serveur, msg_envoyer)
    
        thread_recu.start()
        thread_envoyer.start()
    
        thread_recu.join()
        thread_envoyer.join()
    
    print("Fermeture de la connexion")
    # Fermeture de la connexion
    connexion_avec_serveur.close()
    

    Merci de votre aide :D

    -
    Edité par Kevin Dupeyrat 24 septembre 2017 à 1:35:23

    • Partager sur Facebook
    • Partager sur Twitter

    Problèmes thread Tchat Console

    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
    • Editeur
    • Markdown