Superposition de messages lors de l'envoi via un socket
Bonjour,
J'ai réalisé un tchat basique fonctionnant sur le protocole TCP/IP avec une architecture clients/serveur (en PyQt, mais ceci n'a pas d'importance ici).
Le client est composé d'un QTextEdit où j'affiche la conversation, d'un QListWidget qui affiche la liste des personnes connectés, et enfin d'un QLineEdit (et d'un bouton) pour envoyer les messages au serveur qui s'occupe de renvoyer le message à tout le monde.
Ca ressemble à ça :
http://img10.imageshack.us/img10/244...0110701131.png
Voici le code de mon serveur :
Code:
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
| # -*- coding: utf-8 -*-
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 = []
self.pseudos = []
def wait_for_clients(self):
while True:
client, address = self.socket.accept()
self.clients.append(client)
t = ListeningThread(self.clients, client, self.pseudos)
t.start()
class ListeningThread(threading.Thread):
def __init__(self, clients, client, pseudos):
threading.Thread.__init__(self)
self.clients = clients
self.client = client
self.pseudos = pseudos
def run(self):
name = self.client.recv(1024)
print type(name)
address = self.client.getsockname()
message = "<font color='gray'><b>" + name + "</b> est connecté</font>"
if len(self.pseudos) > 0:
self.client.send("MAJsuperman " + str(','.join(self.pseudos)))
self.send_to_all(message)
self.pseudos.append(name)
self.send_to_all("JOINsuperman " + name)
while True:
message = self.client.recv(1024)
if message == "":
self.clients.remove(self.client)
message = "<font color='gray'><b>" + name + "</b> s'est déconnecté</font>"
self.send_to_all("LEFTsuperman " + name)
self.pseudos.remove(name)
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() |
Comme vous pouvez le voir, j'utilise un message "spécial" pour indiquer aux clients la connexion ou la déconnexion d'une personne pour y afficher (ou retirer) son pseudo dans la QListWidget.
Cependant, lorsque je fais appel à la méthode send_to_all 2 fois à la suite, du côté du client je ne reçois pas 2 messages séparément, mais je reçois un seul message avec les 2 messages concaténés...
Concrètement côté serveur j'envoie :
- "<font color='gray'><b>" + name + "</b> est connecté</font>" d'une part, et :
- "JOINsuperman " + name d'autre part
et côté client, au lieu de recevoir ces messages séparément afin d'afficher le premier message dans le QTextEdit, et de traiter le second message en affichant le pseudo dans la QListWidget, je reçois les 2 messages ensemble en une seule fois...
<font color='gray'><b>" + name + "</b> est connecté</font>JOINsuperman mon_pseudo
A noter que ceci est aléatoire, parfois ça fonctionne, et souvent ce phénomène ce produit... (seulement lors de la connexion/déconnexion vu que je fais plusieurs send() en suivant). Lors d'une discussion tout fonctionne bien.
Si besoin, voici la méthode côté client qui s'occupe de recevoir les messages et de les traiter en fonction :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| def run(self):
while self.running:
message = self.sock.recv(1024)
print 'message recu: ' + message
if message[0:11] == "MAJsuperman":
pseudos = message[12:]
self.emit(SIGNAL("maj"), pseudos)
elif message[0:12] != "JOINsuperman" and message[0:12] != "LEFTsuperman" and message[0:11] != "MAJsuperman":
self.emit(SIGNAL("message_recu"), message)
elif message[0:12] == "JOINsuperman":
pseudo = message[13:]
self.emit(SIGNAL("join"), pseudo)
elif message[0:12] == "LEFTsuperman":
pseudo = message[13:]
self.emit(SIGNAL("left"), pseudo)
QApplication.processEvents() |
Sauriez-vous comment je pourrais y remédier ?
Merci d'avance !