La création d'une simple application de Chat en Python (Sockets)
Je suis en train de créer une simple application de chat à l'aide de sockets (python). Le cas où un client peut envoyer un message au serveur et de simplement diffuser le message à tous les autres clients, à l'exception de celui qui l'a envoyé.
Client a deux fils, qui sont en cours d'exécution pour toujours
send
: Envoyer envoie simplement les propriétaires message au serveur.
receive
: Recevez le message depuis le serveur.
Serveur dispose également de deux fils, qui sont en cours d'exécution pour toujours
accept_cleint
: Pour accepter les connexions entrantes à partir du client.
broadcast_usr
: Accepte le message du client et de diffuser à tous les autres clients.
Mais je suis sortie erronées (Veuillez vous référer à l'image ci-dessous). Tous les threads suppose d'être actif tout le temps, mais Quelques fois le client peut envoyer un message parfois, il ne peut pas. Disons, par exemple, Tracey envoie "salut" 4 fois mais ce n'est pas diffusée, Lorsque Jean dit 'au revoir' 2 fois, puis 1 fois message obtient diffusées. Il semble qu'il y est quelques thread synchronization
problème à rompre, je ne suis pas sûr. S'il vous plaît dites-moi ce qui ne va pas.
Ci-dessous est le code.
chat_client.py
import socket, threading
def send():
while True:
msg = raw_input('\nMe > ')
cli_sock.send(msg)
def receive():
while True:
sen_name = cli_sock.recv(1024)
data = cli_sock.recv(1024)
print('\n' + str(sen_name) + ' > ' + str(data))
if __name__ == "__main__":
# socket
cli_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# connect
HOST = 'localhost'
PORT = 5023
cli_sock.connect((HOST, PORT))
print('Connected to remote host...')
uname = raw_input('Enter your name to enter the chat > ')
cli_sock.send(uname)
thread_send = threading.Thread(target = send)
thread_send.start()
thread_receive = threading.Thread(target = receive)
thread_receive.start()
chat_server.py
import socket, threading
def accept_client():
while True:
#accept
cli_sock, cli_add = ser_sock.accept()
uname = cli_sock.recv(1024)
CONNECTION_LIST.append((uname, cli_sock))
print('%s is now connected' %uname)
def broadcast_usr():
while True:
for i in range(len(CONNECTION_LIST)):
try:
data = CONNECTION_LIST[i][1].recv(1024)
if data:
b_usr(CONNECTION_LIST[i][1], CONNECTION_LIST[i][0], data)
except Exception as x:
print(x.message)
break
def b_usr(cs_sock, sen_name, msg):
for i in range(len(CONNECTION_LIST)):
if (CONNECTION_LIST[i][1] != cs_sock):
CONNECTION_LIST[i][1].send(sen_name)
CONNECTION_LIST[i][1].send(msg)
if __name__ == "__main__":
CONNECTION_LIST = []
# socket
ser_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind
HOST = 'localhost'
PORT = 5023
ser_sock.bind((HOST, PORT))
# listen
ser_sock.listen(1)
print('Chat server started on port : ' + str(PORT))
thread_ac = threading.Thread(target = accept_client)
thread_ac.start()
thread_bs = threading.Thread(target = broadcast_usr)
thread_bs.start()
Juste pour info, Twisted est une bibliothèque Python pour faire des filetée serveurs.
OriginalL'auteur Atinesh | 2016-03-17
Vous devez vous connecter pour publier un commentaire.
Ok j'ai menti dans mon commentaire plus tôt, désolé. La question est en fait dans le
broadcast_usr()
fonction sur le serveur. C'est le blocage de l'recv()
méthode et la prévention de toutes, mais l'utilisateur sélectionnée de parler en même temps qu'il progresse à travers lesfor
boucle. Pour résoudre ce problème, j'ai changé le server.py programme pour générer un nouveau broadcast_usr thread pour chaque connexion client qu'il accepte. J'espère que cette aide.sen_name = cli_sock.recv(1024)
etdata = cli_sock.recv(1024)
à côté client, les deux reçoivent le nom de l'expéditeur et le message. Veuillez consulter ci-dessous la capture d'écran postimg.org/image/3mnwmuyvjOriginalL'auteur pholtz
J'ai essayé de contourner le bug que vous avez dit @Atinesh. Le client sera demandé un nom d'utilisateur une fois et cette "uname" sera inclus dans les données à envoyer. Voir ce que j'ai fait pour le "envoyer " la fonction.
Pour faciliter la visualisation, j'ai ajouté un '\t' pour tous les messages reçus.
Vous devez également modifier votre code serveur en conséquence.
server.py
Choses qui a changé dans le côté serveur sont: l'utilisateur qui s'est connecté, et l'utilisateur qui a parlé n'est pas vu plus. Je ne sais pas si cela signifie que si votre but est de connecter les clients. Peut-être que si vous souhaitez contrôler strictement les clients via le serveur, il pourrait y avoir un autre moyen.
oups. n'a pas remarqué. Merci pour le tuyau. 🙂
OriginalL'auteur ajdr