Bonjour à tous,
Je m'attaque à PyQt en créant/bidouillant un Chat en réseaux.
Je suis actuellement confronté à un bug pour le moins étrange (à moins que ce soit une feature).
Je ne reçois que la première lettre des envois du serveur... alors qu'à un moment donné cela fonctionnait très bien (enfin plus ou moins).
En gros je devrais recevoir : shaoling : coucou, mais je reçois seulement s.
Pourtant le serveur reçoit bien tout ce qu'il faut (ça affiche en console ce que ça devrait renvoyer).
Donc soit il y a un problème lors de l'envoie server -> client, soit il y a un problème sur l'affichage du client...
Vous pouvez télécharger les sources ci-dessous, mais je vous affiche quand même mon code.
http://www.megaupload.com/?d=QWMW22EH
Fichier server.py :
Fichier connexion.py : # Fenetre de 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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 import sys, socket import threading class Server: def __init__(self, address): self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.socket.bind(address) self.socket.listen(5) self.clients = [] def wait_for_clients(self): while True: client, address = self.socket.accept() self.clients.append(client) t = ListeningThread(self.clients, client) t.start() class ListeningThread(threading.Thread): def __init__(self, clients, client): threading.Thread.__init__(self) self.clients = clients self.client = client def run(self): name = self.client.recv(1024) address = self.client.getsockname() message = "<b>%s</b> %s connected" % (name, address) self.send_to_all(message) while True: message = self.client.recv(1024) if message == "": self.clients.remove(self.client) message = "<b>" + name + "</b> disconnected" self.send_to_all(message) break message = "<b>" + name + "</b>: " + message self.send_to_all(message) def send_to_all(self, message): print message for client in self.clients: client.send(message) if len(sys.argv) != 3: print """Usage: python server.py ip port example: python server.py localhost 54321""" sys.exit() address = sys.argv[1], int(sys.argv[2]) server = Server(address) server.wait_for_clients()
Fichier chat.py : # Fenetre principale du tchat
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 # -*- coding: utf-8 -*- import sys import socket from PyQt4.QtCore import * from PyQt4.QtGui import * from chat import FenetreChat PORT=54321 class FenetreConnexion(QDialog): """Fenêtre de connexion de l'application iTchat""" def __init__(self, parent=None): QDialog.__init__(self, parent) self.setFixedSize(300,150) self.setWindowTitle('Connexion') size_ecran = QDesktopWidget().screenGeometry() size_fenetre = self.geometry() # Serveur self.layout_serveur = QHBoxLayout() self.serveur = QLabel('Serveur : ') self.input_serveur = QLineEdit() self.layout_serveur.addWidget(self.serveur) self.layout_serveur.addWidget(self.input_serveur) # Pseudo self.layout_pseudo = QHBoxLayout() self.pseudo = QLabel('Pseudo : ') self.input_pseudo = QLineEdit() self.layout_pseudo.addWidget(self.pseudo) self.layout_pseudo.addWidget(self.input_pseudo) # Boutons OK et Quitter self.layout_boutons = QHBoxLayout() self.bouton_ok = QPushButton('Se Connecter') self.bouton_quitter = QPushButton('Quitter') QDialog.connect(self.bouton_ok, SIGNAL("clicked()"), self.check_infos) QDialog.connect(self.bouton_quitter, SIGNAL("clicked()"), quit) self.bouton_quitter.clicked.connect(quit) self.layout_boutons.addWidget(self.bouton_ok) self.layout_boutons.addWidget(self.bouton_quitter) # Layout principal self.layout_principal = QVBoxLayout() self.layout_principal.addLayout(self.layout_serveur) self.layout_principal.addLayout(self.layout_pseudo) self.layout_principal.addLayout(self.layout_boutons) self.setLayout(self.layout_principal) # on centre la fenetre self.move((size_ecran.width()-size_fenetre.width())/2, (size_ecran.height()-size_fenetre.height())/2) def check_infos(self): """Vérifie les informations entrées dans le formulaire de connexion""" self.serveur = self.input_serveur.text().trimmed() self.pseudo = self.input_pseudo.text().trimmed() if self.serveur == '' or self.pseudo == '': msg = QMessageBox.warning(self, u"Erreur !", u"Veuillez indiquer l'adresse du serveur ainsi que votre pseudo !") elif not self.pseudo.contains(QRegExp(r"^\w+$")): msg = QMessageBox.warning(self, u"Erreur !", u"Votre pseudo ne doit contenir que des lettres, chiffres et underscores !") else: self.connexion(self.serveur, self.pseudo) def connexion(self, serveur, pseudo): """Etablit la connexion au serveur""" # dès que tout est OK, on tente la connexion self.sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: self.sock.connect((serveur, PORT)) except socket.gaierror: QMessageBox.critical(self, u"Erreur !", u"Impossible de se connecter au serveur indiqué !") return print "Connexion au serveur > %s : %s avec le pseudo %s" % (serveur, PORT, pseudo) self.sock.send(pseudo) # Affichage de la fenetre principale tchat = FenetreChat(self.sock, self) tchat.show() # On cache la fenetre de connexion self.hide() if __name__ == "__main__": app = QApplication(sys.argv) connexion = FenetreConnexion() connexion.show() sys.exit(app.exec_())
Et enfin fichier client.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
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 # -*- coding: utf-8 -*- from PyQt4.QtCore import * from PyQt4.QtGui import * class FenetreChat(QDialog): """Fenêtre principale de l'application iTchat""" def __init__(self, sock, parent=None): QDialog.__init__(self, parent) self.sock = sock self.parent = parent self.resize(600,500) self.setMinimumWidth(600) # Largeur minimale self.setMinimumHeight(500) # Hauteur minimale self.setWindowTitle('iTchat') size_ecran = QDesktopWidget().screenGeometry() size_fenetre = self.geometry() # on centre la fenetre self.move((size_ecran.width()-size_fenetre.width())/2, (size_ecran.height()-size_fenetre.height())/2) # Layouts du haut, du bas, et principal comprenant haut et bas self.layout_haut = QHBoxLayout() self.layout_bas = QHBoxLayout() self.layout_principal = QVBoxLayout() # Contenu du layout_haut self.tchat = QTextEdit() self.tchat.setReadOnly(True) self.tchat.append(u"<font color='red'><b>Connecté.</b></font>") self.connectes = QListWidget() self.connectes.setMaximumWidth(200) # Largeur maximale self.layout_haut.addWidget(self.tchat) self.layout_haut.addWidget(self.connectes) # Contenu du layout_bas self.input_texte = QLineEdit() self.bouton_envoyer = QPushButton('Envoyer') self.bouton_envoyer.setDefault(True) self.layout_bas.addWidget(self.input_texte) self.layout_bas.addWidget(self.bouton_envoyer) # Contenu du layout_principal self.layout_principal.addLayout(self.layout_haut) self.layout_principal.addLayout(self.layout_bas) self.setLayout(self.layout_principal) QWidget.connect(self.bouton_envoyer, SIGNAL("clicked()"), self.envoyer) self.listening_thread = ListeningThread(self, self.sock) self.connect(self.listening_thread, SIGNAL("message_recu"), self.recevoir) self.listening_thread.start() def envoyer(self): message = self.input_texte.text().trimmed() if message != '': self.sock.send(message) self.input_texte.setText('') def recevoir(self, message): self.tchat.append(message) def closeEvent(self, event): self.listening_thread.terminate() self.sock.close() QWidget.deleteLater(self) self.parent.close() event.accept() class ListeningThread(QThread): def __init__(self, parent, socket): QThread.__init__(self, parent) self.parent = parent self.socket = socket self.running = True def run(self): while self.running: message = self.socket.recv(1024) self.emit(SIGNAL("message_recu"), message) QApplication.processEvents()
Pour lancer le serveur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 import sys #from PyQt4.QtCore import * from PyQt4.QtGui import * from connexion import FenetreConnexion app = QApplication(sys.argv) fenetre = FenetreConnexion() fenetre.show() app.exit(app.exec_())
Pour lancer le client :$ python server.py localhost 54321
Il faut entrer localhost dans la case client, et le pseudo que vous souhaitez.$ python client.py
Si quelqu'un pouvait m'indiquer d'où provient l'erreur je lui en serait reconnaissant, mes recherches n'ont rien données...
Merci d'avance !
Partager