Partage
  • Partager sur Facebook
  • Partager sur Twitter

Socket /Thread python

Sujet résolu
    14 janvier 2019 à 20:27:21

    Bonjour. Je n'arrive pas à faire écouter mon serveur python en utilisant le multi-threading mais j'ai pas d'erreur pour autant. Je ne sais pas quoi faire, quelqu'un aurait il une idée ?

    import socket
    from threading import Thread
    
    class Serv(Thread):
        def __init__(self):
            Thread.__init__(self)
            self.soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.soc.bind(('',15552))
        def run(self):
    
            self.soc.listen(5)
            while 1:
                client, address = self.soc.accept()
                response = client.recv(255)
    
            while response != "":
    
                if response != "":
                    print (response.decode())
                response = client.recv(255)
    
    serveur = Serv()
    serveur.start()
    

    -
    Edité par theoriol 14 janvier 2019 à 20:28:17

    • Partager sur Facebook
    • Partager sur Twitter
      14 janvier 2019 à 22:03:18

      thelinekioubeur a écrit: > Pour pouvoir écouter plus qu'un seul message envoyé par le même client

      • Partager sur Facebook
      • Partager sur Twitter
        14 janvier 2019 à 22:52:48

        Je crois que le principe c'est que chaque client ait un thread séparé :

        from socket import socket, AF_INET, SOCK_STREAM, timeout
        from threading import Thread
        
        
        log = print
        
        
        class ErrorLevels:
        
            OK = "OK"
            ERROR = "ERROR"
        
        
        class Server(Thread):
        
        
            def __init__(self):
        
                Thread.__init__(self)
        
                self.socket = socket(AF_INET, SOCK_STREAM)
                self.socket.bind(("", 25000))
                self.socket.settimeout(0.5)
        
                self.running = False
                self.client_pool = []
        
            def client_handling_stopped(self, client, error_level, error_msg):
        
                log(f"Le gérant de {client.address} s'est arrêté avec le niveau d'erreur {error_level} ({error_msg})")
        
                self.clean_up()
        
                # self.log_connection_amount()
        
            def log_connection_amount(self):
        
                log(f"Il y a maintenant {len(self.client_pool)} client(s) connecté(s)")
        
            def stop(self):
        
                log(f"Arrêt du serveur")
        
                for client in self.client_pool:
                    client.close_connection()
        
                self.running = False
        
            def clean_up(self):
                """
                Enlève tous les gérants de clients innactifs de la liste des gérants de clients
                """
        
                self.client_pool = [client for client in self.client_pool if client.alive]
        
            def run(self):
        
                log(f"Démarrage du serveur")
        
                self.running = True
        
                self.socket.listen(5)
        
                while self.running:
        
                    try:
        
                        client, address = self.socket.accept()
        
                    except timeout:
                        continue # on retourne au début de la boucle jusqu'à avoir un client 
        
                    log(f"Connexion depuis {address}")
        
                    client_handling = ClientHandling(client, address, self.client_handling_stopped)
                    client_handling.start()
                    self.client_pool.append(client_handling)
        
                    # self.log_connection_amount()
        
        
        class ClientHandling(Thread):
        
        
            def __init__(self, client, address, exit_callback):
        
                Thread.__init__(self)
        
                self.client = client
                self.address = address
                self.exit_callback = exit_callback # une fonction qui devra être appelée lorsque cet objet sera devenu inactif
                self.alive = True
        
            def _stop(self, error_level, error_msg):
        
                self.alive = False
                self.close_connection()
                self.exit_callback(self, error_level, error_msg)
        
            def close_connection(self):
        
                self.alive = False
                self.client.close()
                log(f"Fin de la communication avec {self.address}")
        
            def run(self):
        
                try:
        
                    response = self.client.recv(255)
        
                    while response:
                        print(response.decode("utf-8"))
                        response = self.client.recv(255)
        
                except ZeroDivisionError:
        
                    self._stop(ErrorLevels.ERROR, "Une division par zéro à été tentée")
        
                except ConnectionAbortedError:
        
                    if self.alive: # innatendu
                        self._stop(ErrorLevels.ERROR, "La connexion à été abandonnée")
        
                    else: # on est dans le cas où le gérant est volontairement arrêté
                        return # on arrête donc tout, plus besoin de faire quoi que ce soit
        
                self._stop(ErrorLevels.OK, "Le client a fermé la connection")
        
        
        try:
        
            server = Server()
            server.start()
        
            while True: continue
        
        except KeyboardInterrupt:
        
        	server.stop()
        	server.join()

        Bon c'est pas parfait, on voudrait par exemple se sécuriser un peu plus avec des contexts managers, et faire remonter les erreurs avec plus de détail, mais le principe est là.

        Aussi, le client que j'ai utilisé pour tout vérifier :

        from socket import socket, AF_INET, SOCK_STREAM
        
        
        socket = socket(AF_INET, SOCK_STREAM)
        socket.connect(("localhost", 25000))
        
        
        while True:
        
        	msg = input(": ")
        
        	if msg:
        
        		print(f"Envoi de '{msg}'")
        
        		msg = msg.encode("utf-8")
        		socket.send(msg)
        
        	else:
        
        		print("Arrêt")
        		socket.send("".encode("utf-8"))
        		socket.close()
        		break
        




        -
        Edité par digammaF 14 janvier 2019 à 22:56:25

        • Partager sur Facebook
        • Partager sur Twitter

        typage structurel ftw

          14 janvier 2019 à 23:18:29

          digammaF a écrit: >

          merci pour le coup de main, je comprend mieux comment sa fonctionne.

          • Partager sur Facebook
          • Partager sur Twitter

          Socket /Thread python

          × 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