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 :

Interrompre la connexion d'un socket commandé par un GUI


Sujet :

Réseau/Web Python

  1. #1
    Membre régulier
    Inscrit en
    juillet 2013
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : juillet 2013
    Messages : 73
    Points : 111
    Points
    111
    Par défaut Interrompre la connexion d'un socket commandé par un GUI
    Bonjour,

    (J'ai posté ce message sur une autre discussion et il m'a été conseillé d'en ouvrir une nouvelle)

    J'essaye de faire un GUI côté serveur ; est-il possible de faire une interface graphique autour du serveur avec un bouton 'Quit' (en Tkinter) qui interromps la connexion ?

    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
    import tkinter as tk
    import socket
     
    HOSTPORT = ('localhost',1234)
    BUFSIZE = 1024
    CODE = 'utf8'
     
    class App(tk.Tk) :
        def __init__(self) :
            tk.Tk.__init__(self)
            self.geometry('100x100')
     
            # Create socket
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.bind(HOSTPORT)
     
            # Start connection
            button = tk.Button(self, text='Listen', command=self.listen)
            button.pack()
     
            # Close GUI, even if connection opened
            button = tk.Button(self, text='Close program', command=self.destroy)
            button.pack()
     
        def listen(self) :
            while True :
                self.socket.listen(5)
                conn, address = self.socket.accept()
                data = conn.recv(BUFSIZE)
                print('Client says %s'%data.decode(CODE))
            conn.close()
            self.socket.close()
     
    app = App()
    app.mainloop()
    Je suis bloqué par la boucle infinie qui bloque ma fenêtre graphique, et en particulier le bouton 'Close program' que je souhaitais avoir à disposition pour arrêter "d'écouter".

    Est-il nécessaire de créer un client "local" pour piloter le serveur (local également) et utiliser le module select pour que le serveur écoute simultanément les instruction de l'opérateur (côté serveur) et du client (potentiellement machine distante) ?

    Je me considère comme plutôt à l'aide avec le module Tkinter mais les projets que j'ai eu jusqu'à présent n'ont jamais impliqué les modules socket, select et thread que je découvre depuis quelques jours...

    Bien cordialement !

  2. #2
    Membre régulier
    Inscrit en
    juillet 2013
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : juillet 2013
    Messages : 73
    Points : 111
    Points
    111
    Par défaut
    Bonjour,

    J'ai modifié mon compte en incluant la fonction listen() dans un thread + settimeout() ; pensez-vous que le code est optimal ainsi ? Est-il préférable d'utiliser asyncio dans ce cas de figure ?

    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
    import tkinter as tk
    import socket
    import threading
     
    class App(tk.Tk) :
        def __init__(self) :
            tk.Tk.__init__(self)
            self.geometry('100x100')
     
            # Socket
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server.bind(('localhost',1234))
            self.server.settimeout(0.1)
     
            # Button
            self.play = tk.Button(self, text='Play', command=self.modeOn)
            self.play.pack()
     
            # Switch
            self._mode = False
     
        def listen(self) : # Server starts listening
            while self._mode :
                self.server.listen()
                try : self.server.accept()
                except socket.timeout as e : print('running...')
     
        def modeOn(self) :
            print('Activation OK')
            self._mode = True
            self._thread = threading.Thread(target=self.listen)
            self._thread.start()
            self.play.configure(text='Pause', command=self.modeOff)
     
        def modeOff(self) :
            self._mode=False
            self.play.configure(text='Play', command=self.modeOn)
            print('Deactivation OK')
     
    App().mainloop()

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    juin 2008
    Messages
    17 691
    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 : 17 691
    Points : 30 532
    Points
    30 532
    Par défaut
    Salut,

    Citation Envoyé par charliemtx Voir le message
    J'ai modifié mon compte en incluant la fonction listen() dans un thread + settimeout() ; pensez-vous que le code est optimal ainsi ? Est-il préférable d'utiliser asyncio dans ce cas de figure ?
    Au départ, le soucis est qu'on a un environnement multitâche coopératif (tkinter) qui suppose que les callbacks se terminent rapidement (sinon çà gèle) dans lequel on veut planter des appels bloquants (çà attend que le client ait...).

    Pousser les opérations bloquantes dans un thread est une solution (mais alors pas la peine de mettre un timeout puisque çà ne gèle plus l'interface graphique).

    Utiliser des socket non bloquantes et select pourrait en être une autre.

    Mélanger asyncio et tkinter, çà se fait mais c'est compliqué puisqu'on va avoir 2 boucles évènementielles à gérer dans le même thread.

    Il y a plein de solutions, à vous de comprendre comment elles fonctionnent et de choisir la plus adaptée (et plein d'exemples de code sur Internet).

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

Discussions similaires

  1. Connexion http avec un webrelais (relais commandé par ethernet)
    Par michastro dans le forum Web & réseau
    Réponses: 1
    Dernier message: 28/07/2017, 11h12
  2. Réponses: 2
    Dernier message: 23/10/2006, 13h32
  3. Interrompre une connexion ?
    Par BoBoToTo dans le forum Bases de données
    Réponses: 7
    Dernier message: 29/10/2004, 09h26
  4. Couper la connexion d'un socket client...
    Par Higestromm dans le forum Développement
    Réponses: 4
    Dernier message: 28/10/2004, 10h41
  5. Création d'une connexion en ligne de commande
    Par Drahu dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 10/05/2004, 15h19

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