J'essaie donc de faire un petit Tchat, un minuscule truc très simple. Puisqu'il paraît (selon le cours) que j'ai les connaissances nécessaires. Ah Ah
Je n'y arrive donc pas.
Là, tel que c'est, j'ai un décalage : le client 2 reçoit les messages du client 1 uniquement quand il envoie lui-même quelque chose. Et réciproquement.
J'ai dû très très mal m'y prendre
Je vous mets les codes. Le serveur :
import socket
import select
hote = ''
port = 12800
connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_principale.bind((hote, port))
connexion_principale.listen(5)
print("Le serveur écoute à présent sur le port {}".format(port))
serveur_lance = True
clients_connectes = []
clients_sockets = {}
n = ' '
while serveur_lance:
connexions_demandees, wlist, xlist = select.select([connexion_principale],
[], [], 0.05)
for connexion in connexions_demandees:
connexion_avec_client, infos_connexion = connexion.accept()
clients_connectes.append(connexion_avec_client)
clients_a_lire = []
try:
clients_a_lire, wlist, xlist = select.select(clients_connectes,[], [], 0.05)
except select.error:
pass
else:
for client in clients_a_lire :
if client not in clients_sockets :
client.send(b"Bienvenue sur le Tchat")
n = client.recv(1024)
n = n.decode()
clients_sockets.setdefault(connexion_avec_client,n)
msg_recu = client.recv(1024)
for client_tchat in clients_sockets :
msg_a_transmettre = clients_sockets[client_tchat].encode()\
+ b" : " + msg_recu
client_tchat.send(msg_a_transmettre)
if msg_recu == "fin":
serveur_lance = False
print("Fermeture des connexions")
for client in clients_connectes:
client.close()
connexion_principale.close()
et le client :
import socket
hote = "localhost"
port = 12800
connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_avec_serveur.connect((hote, port))
print("Connexion établie avec le serveur sur le port {}".format(port))
print("Quel est votre nom ?")
msg_a_envoyer = b""
while msg_a_envoyer != b"fin":
msg_a_envoyer = input("> ")
# Peut planter si vous tapez des caractères spéciaux
msg_a_envoyer = msg_a_envoyer.encode()
# On envoie le message
connexion_avec_serveur.send(msg_a_envoyer)
msg_recu = connexion_avec_serveur.recv(1024)
print(msg_recu.decode()) # Là encore, peut planter s'il y a des accents
print("Fermeture de la connexion")
connexion_avec_serveur.close()
En gros j'ai bien sûr repris les codes du cours, et j'essaie de les modifier mais....c'est la misère
Je ne sais même pas, à ce stade, si mon problème bien du serveur ou du client.
Ça vient forcément du serveur, le client 2 n'est pas censé recevoir les messages destinés au client 1.
EDIT : Erreur de ma part, j'ai mal compris le problème. C'est juste que la fonction input est bloquante, donc tant que tu n'envoie rien, la boucle reste bloquée à la ligne 15.
- Edité par LoupSolitaire 19 juillet 2019 à 18:37:16
Pas de solution simple à ma connaissance, à part utiliser deux programmes clients, un pour la réception, et un pour l'envoi, les deux exécutés dans deux consoles différentes.
Pour les solutions plus compliquées mais qui évitent de bricoler avec deux consoles, il faudrait sans doute utiliser curses ( https://docs.python.org/3/howto/curses.html ) pour faire une jolie interface en mode texte (dans la console donc) avec une zone de saisie non bloquante et une zone d'affichage des messages. Ou tkinter pour le faire en mode graphique sur le même principe.
- Edité par LoupSolitaire 20 juillet 2019 à 17:22:40
Une solution serait de créer un thread côté client pour lire et afficher ce qui est expédié par le serveur. Pendant ce temps, le programme principal exécute input et les envois vers le serveur.
Ce problème résolu d'autres devraient apparaître...
import socket
import select
hote = ''
port = 12800
connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_principale.bind((hote, port))
connexion_principale.listen(5)
print("Le serveur écoute à présent sur le port {}".format(port))
serveur_lance = True
clients_connectes = []
clients_sockets = {}
n = ' '
while serveur_lance:
connexions_demandees, wlist, xlist = select.select([connexion_principale],
[], [], 0.05)
for connexion in connexions_demandees:
connexion_avec_client, infos_connexion = connexion.accept()
clients_connectes.append(connexion_avec_client)
clients_a_lire = []
try:
clients_a_lire, wlist, xlist = select.select(clients_connectes,[], [], 0.05)
except select.error:
pass
else:
for client in clients_a_lire :
if client not in clients_sockets :
client.send(b"Bienvenue sur le Tchat")
n = client.recv(1024)
n = n.decode()
clients_sockets.setdefault(connexion_avec_client,n)
msg_recu = client.recv(1024)
for client_tchat in clients_sockets :
msg_a_transmettre = clients_sockets[client_tchat].encode()\
+ b" : " + msg_recu
client_tchat.send(msg_a_transmettre)
print(msg_a_transmettre.decode())
if msg_recu == "fin":
serveur_lance = False
print("Fermeture des connexions")
for client in clients_connectes:
client.close()
connexion_principale.close()
Les threads :
from threading import Thread, RLock
class Client_Rec(Thread):
"""Thread chargé simplement d'afficher les message envoyés par le serveur."""
def __init__(self,connexion):
Thread.__init__(self)
self.connexion_avec_serveur = connexion
def run(self):
"""Code à exécuter pendant l'exécution du thread."""
msg_recu = ''
while msg_recu :
msg_recu = self.connexion_avec_serveur.recv(1024)
print(msg_recu.decode())
verrou = RLock()
class Client_Envoi(Thread):
"""Thread chargé simplement d'envoyer des messages au serveur."""
def __init__(self, connexion):
Thread.__init__(self)
self.connexion_avec_serveur = connexion
def run(self):
"""Code à exécuter pendant l'exécution du thread."""
msg_a_envoyer = b""
while msg_a_envoyer != b"fin":
with verrou:
msg_a_envoyer = input("> ")
msg_a_envoyer = msg_a_envoyer.encode()
self.connexion_avec_serveur.send(msg_a_envoyer)
Les clients :
import socket
from Tchat_client_thread import*
hote = "localhost"
port = 12800
connexion_avec_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_avec_serveur.connect((hote, port))
print("Connexion établie avec le serveur sur le port {}".format(port))
print("Quel est votre nom ?")
thread_Rec = Client_Rec(connexion_avec_serveur)
thread_Envoi = Client_Envoi(connexion_avec_serveur)
thread_Rec.start()
thread_Envoi.start()
thread_Rec.join()
thread_Envoi.join()
print("Fermeture de la connexion")
connexion_avec_serveur.close()
Et le résultat ...
un joyeux bordel. Alors ça fonctionne pas : les clients ne reçoivent pas les messages des autres clients (c'est ballot, vous en conviendrez). J'ai mis un print côté serveur, pour voir comment les threads fonctionnaient, et il est là le joyeux bordel. Parfois ça s'affiche en retard, parfois non, le tout mélangé, et parfois plusieurs affichages.
Doit y avoir un problème quelque part. Si ça se trouve, y en a partout. Pourtant, j'était contente de moi j'avais l'impression que c'était pas si mal
Quelqu'un y comprend quelque chose, et pourrait me dire où ça cloche ?
Créer un petit Tchat (simple)
× 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.
Blond, bouclé, toujours le sourire aux lèvres...
Blond, bouclé, toujours le sourire aux lèvres...