【发布时间】:2017-08-19 17:15:11
【问题描述】:
我的暑期任务是在 python 上使用套接字创建一个聊天室,使用主套接字作为连接到所有其他“客户端”套接字的服务器,每次客户端向服务器发送消息时,服务器将其发送给除发送它的客户端之外的其他所有人。问题是我需要做到这一点,以便您可以同时编写消息并接收它们,这是我不知道该怎么做的事情,所以我接受了朋友的建议并尝试使用多线程来做到这一点。
这就是我现在所拥有的,它应该会变得更复杂,但这是非常基本的部分:
客户
import socket
import thread
import time
def receive_messages(recieve_socket):
while True:
print recieve_socket.recv(1024)
def send_messages(send_socket):
while True:
data = raw_input()
send_socket.send(data)
def main():
my_socket = socket.socket()
my_socket.connect(('127.0.0.1', 8822))
thread.start_new_thread(send_messages, (my_socket, ))
thread.start_new_thread(receive_messages, (my_socket, ))
time.sleep(1) #this delay lets the threads kick in, otherwise the thread count is zero and it crashes
while thread._count() > 1:
pass
if __name__ == '__main__':
main()
服务器
import socket
import select
waiting_messages = []
users = []
def add_new_user(user_socket):
new_socket, address = user_socket.accept()
users.append(new_socket)
print "A new user has joined"
def remove_user(user_socket):
users.remove(user_socket)
print "A user has left"
def send_waiting_messages(wlist):
for message in waiting_messages:
receiving_socket, data = message
if receiving_socket in wlist:
receiving_socket.send(data)
waiting_messages.remove(message)
def spread_messages(message, sending_user):
receiving_list = users
receiving_list.remove(sending_user)
for user in receiving_list:
waiting_messages.append((user, message))
print "A user has sent a message"
def main():
server_socket = socket.socket()
server_socket.bind(('0.0.0.0', 8822))
server_socket.listen(5)
# users = []
# messages_to_send = []
while True:
rlist, wlist, xlist = select.select([server_socket] + users, users, [])
for current_socket in rlist:
if current_socket is server_socket:
add_new_user(server_socket)
else:
data = current_socket.recv(1024)
if data == "quit":
remove_user(current_socket)
else:
spread_messages(data, current_socket)
send_waiting_messages(wlist)
if __name__ == '__main__':
main()
问题是当我尝试运行它时,第一条消息工作正常,但在第二条消息之后,服务器只是发送了很多空白消息并停止发送我发送的消息。
非常感谢您在这件事上的帮助。
【问题讨论】:
-
事实上,你可以在没有多线程的情况下完成它,只使用
select模块。看看this。另外,避免使用thread模块。请改用threading。 -
在我看来,通过使用单独的线程执行阻塞套接字操作并使用thread-safe queues 来暂存消息,您会更轻松。
-
@SamChats 我只在客户端中使用线程来同时接收和发送消息。此外,您发送的示例与我的示例几乎相同,只是您的示例只发送给有空的人,而不是不空的人。不过感谢您的帮助。
标签: python sockets network-programming python-multithreading