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()
share|improve this question

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.