我正在尝试使用套接字 (python) 创建一个简单的聊天应用程序。客户端可以向服务器发送消息,而服务器只需将消息广播给除发送消息的客户端之外的所有其他客户端。
客户端有两个线程,一直在运行
send
: Send simply sends the cleints message to server.
receive
: Receive the message from the server.
Server也有两个线程,一直在运行
accept_cleint
: To accept the incoming connection from the client.
broadcast_usr
: Accepts the message from the client and just broadcast it to all other clients.
但是我得到了错误的输出(请引用下图)。所有线程都应该一直处于事件状态,但有时客户端可以发送消息,有时却不能。例如,Tracey 发送了 4 次“嗨”但没有广播,当约翰说“再见”2 次然后 1 次它的消息被广播。服务器似乎有一些线程同步
问题,我不确定。请告诉我怎么了。
下面是代码。
聊天客户端.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()
聊天服务器.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()
最佳答案
好的,我之前在评论中撒了谎,抱歉。问题实际上出在服务器上的 broadcast_usr()
函数中。它在 recv()
方法中阻塞,并在 for
循环中阻止除当前选定用户之外的所有用户同时讲话。为了解决这个问题,我更改了 server.py 程序,为它接受的每个客户端连接生成一个新的 broadcast_usr 线程。我希望这会有所帮助。
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)
thread_client = threading.Thread(target = broadcast_usr, args=[uname, cli_sock])
thread_client.start()
def broadcast_usr(uname, cli_sock):
while True:
try:
data = cli_sock.recv(1024)
if data:
print "{0} spoke".format(uname)
b_usr(cli_sock, uname, data)
except Exception as x:
print(x.message)
break
def b_usr(cs_sock, sen_name, msg):
for client in CONNECTION_LIST:
if client[1] != cs_sock:
client[1].send(sen_name)
client[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()
关于python - 在 Python 中创建一个简单的聊天应用程序(套接字),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36060346/