I'm currently learning Python and I have to build a simple labyrinth game that we play in the console on the network. I dig a bit into Python basic network programming and I decided to build a simple console chat to practice. I came up with this code, however, I'm pretty sure it won't work on Windows because of the client class (which isn't really needed here but I'll need it for my game to handle username and so on) and I have no Windows machine/VM for now to test it.
How can I make it more efficient? Indeed, if a user is writing a msg and the server sends one, it will "cut" the user input. On Linux, I could use select
on sys.stdin and therefore wait for user to write in msg to display the server one. But on Windows, I can't do this.
server.py
# -*-coding:Utf-8 -*
import socket
import select
from donnees import *
connexion_principale = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_principale.bind(('', port))
connexion_principale.listen(5)
print("Le serveur écoute sur le port {}.".format(port))
serveur_lance = True
#clients_co = []
clients = []
i = 0
while serveur_lance:
#On vérifie si de nouveaux clients souhaitent se connecter
connexions_demandes, wlist, xlist = select.select([connexion_principale], [], [], 0.1)
#On ajoute les clients éventuels qui souhaitent se co
for connexion in connexions_demandes:
connexion_client, infos_connexion = connexion.accept()
#On ajoute le socket a la liste des clients en créant un objet de classe Client
clients.append(Client(connexion_client))
clients[i].id = i+1
clients[i].nom = "Joueur" + str(clients[i].id)
#clients_co.append(connexion_client)
clients[i].socket.send(b"Hello You.")
i += 1
try:
clients_a_lire, wlist, rlist = select.select(clients, [], [], 0.1)
except select.error:
pass
else:
for client in clients_a_lire:
msg_recu = client.socket.recv(1024)
for destinataire in clients:
if destinataire.id != client.id:
msg_env = "[" + client.nom + "]: " + msg_recu.decode()
destinataire.socket.send(msg_env.encode())
if msg_recu == b"fin":
serveur_lance = False
#Fermer la connexion
print("Fermeture de la connexion")
for client in clients:
client.socket.close()
connexion_principale.close()
client.py
# -*-coding:Utf-8 -*
import socket
from donnees import *
import sys
from threading import Thread
import select
import time
class Listen(Thread):
"""Thread qui écoute les msg du serveur"""
def __init__(self, connexion_serveur):
Thread.__init__(self)
#self.connexion_serveur = connexion_serveur
def run(self):
"""Background job"""
while 1:
try:
serveur_lire, wlist, rlist = select.select([connexion_serveur], [], [])
except:
sys.exit(0)
else:
for serveur in serveur_lire:
msg_serveur = serveur.recv(1024)
if not msg_serveur: sys.exit(0)
time.sleep(0.1)
sys.stdout.write("\n" + msg_serveur.decode() + "\n")
sys.stdout.write("[Me]: ")
sys.stdout.flush()
connexion_serveur = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connexion_serveur.connect(('localhost', port))
print("Connecté avec le serveur sur le port {}".format(port))
l = Listen(connexion_serveur)
l.start()
msg_env = b""
while msg_env != b"fin":
sys.stdout.write("[Me]: ")
sys.stdout.flush()
msg_env = sys.stdin.readline()
msg_env = msg_env.split("\n")[0]
msg_env = msg_env.encode()
connexion_serveur.send(msg_env)
print("Fermeture de la connexion")
connexion_serveur.close()
donnees.py
# -*-coding:Utf-8 -*
port = 12800
class Client(object):
"""Classe contenant le client et ses identifiants"""
def __init__(self, sock):
self.nom = str()
self.id = int()
self.socket = sock
def fileno(self):
return self.socket.fileno()