Bonjour à tous,
je m'explique, je suis entrain de m'amuser à faire un petit serveur (de tchat).
Pour l'exemple j'ai créer une fenêtre glade avec un bouton et un TextBox (Je sait ... petite réminiscence VB je ferrai 2 ave patter et un ave Maria !!)
Le bouton déclenche une fonction START_SRV() qui a son tour déclenche le Multi-Thread serveur qui va attendre les connexion des clients.
le problème c'est que des que je presse mon bouton ma fenêtre gèle !!!
Pour l'exemple j'ai retirer tout les test que j'avais fait avec gtk.gdk.Thread_init() mais je l'ai essayer dans tout les sens !!!
Je comprend bien qu'il faudrait que ma GUI et mon serveur soit des Thread séparé mais dans la pratique ... je fait comment ? ... parce que j'ai beau tout essayer je vois bien qu'en fait je lance un Thread dans un Thread.
je vous ai mi ci dessous :
- le fichier qui démarre ma GUI
- La fonction START-SRV() (Sans les import)
- La class du serveur (Pardon s'il s'appel ThreadClient ... pas encore changé !! :-) )
Si quelqu'un arrive a me dépanner c'est génial parce que la je suis vraiment dans les choux :-)
Je vous remercie tous d'avance :-)
P.S: Pardon pour la propreté du code et les 2 ou 3 truc bizarre mais suis débutant. :-)
Code------
Gui [TestThread.py]
START_SRV [ApiCtrlCommun.py]
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 import pygtk pygtk.require("2.0") import gtk import gtk.glade from ApiCtrlCommun import START_SRV class monprogramme: def __init__(self): self.widgets = gtk.Builder() self.widgets.add_from_file('test.glade') self.widgets.connect_signals(self) def autoConnectb(self): eventHandlers = {} for (itemName,value) in self.__class__.__dict__.items(): if callable(value) and itemName.startswith('gtk_'): eventHandlers[itemName[4:]] = getattr(self,itemName) self.widgets.signal_autoconnect(eventHandlers) def delete(self, source=None, event=None): gtk.main_quit() def on_button1_clicked(self, source=None, event=None): START_SRV("localhost",40000) return True if __name__ == '__main__': app = monprogramme() gtk.main()
Thread Serveur [ApiNetwork.py]
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 def START_SRV(HOST,PORT): mySocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) myThreadClient=ThreadClient try: mySocket.bind((HOST, PORT)) except socket.error: print "La liaison du socket à l'adresse choisie a échoué." sys.exit() print "Serveur prêt, en attente de requêtes ..." mySocket.listen(5) # Attente et prise en charge des connexions demandées par les clients : conn_client = {} # dictionnaire des connexions clients while 1: connexion, adresse = mySocket.accept() # Créer un nouvel objet thread pour gérer la connexion : th = myThreadClient(connexion,conn_client) th.start() print th # Mémoriser la connexion dans le dictionnaire : it = th.getName() # identifiant du thread conn_client[it] = connexion print "Client %s connecté, adresse IP %s, port %s." %\ (it, adresse[0], adresse[1]) # Dialogue avec le client : connexion.send("Vous êtes connecté. Envoyez vos messages.")
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 import threading class ThreadClient(threading.Thread): #dérivation d'un objet thread pour gérer la connexion avec un client def __init__(self, conn ,client_return): threading.Thread.__init__(self) self.connexion = conn self.client_ret=client_return self.str_ret = "Serveur ok" return self.str_ret def run(self): # Dialogue avec le client : nom = self.getName() # Chaque thread possède un nom while 1: msgClient = self.connexion.recv(1024) if msgClient.upper() == "FIN" or msgClient =="": break message = "%s> %s" % (nom, msgClient) print message # Faire suivre le message à tous les autres clients : for cle in self.client_ret: if cle != nom: # ne pas le renvoyer à l'émetteur self.client_ret[cle].send(message) #conn_client[cle].send(message) # Fermeture de la connexion : self.connexion.close() # couper la connexion côté serveur del self.client_ret[nom] #del conn_client[nom] # supprimer son entrée dans le dictionnaire print "Client %s déconnecté." % nom # Le thread se termine ici
Partager