这是我的服务器程序,它如何将从每个客户端收到的数据发送给每个其他客户端?
import socket
import os
from threading import Thread
import thread
def listener(client, address):
print "Accepted connection from: ", address
while True:
data = client.recv(1024)
if not data:
break
else:
print repr(data)
client.send(data)
client.close()
host = socket.gethostname()
port = 10016
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(3)
th = []
while True:
print "Server is listening for connections..."
client, address = s.accept()
th.append(Thread(target=listener, args = (client,address)).start())
s.close()
答案 0 :(得分:9)
如果您需要向所有客户发送消息,则需要以某种方式保留所有客户的集合。例如:
clients = set()
clients_lock = threading.Lock()
def listener(client, address):
print "Accepted connection from: ", address
with clients_lock:
clients.add(client)
try:
while True:
data = client.recv(1024)
if not data:
break
else:
print repr(data)
with clients_lock:
for c in clients:
c.sendall(data)
finally:
with clients_lock:
clients.remove(client)
client.close()
将这部分内容分解为单独的函数可能会更加清晰,例如执行所有发送的broadcast
函数。
无论如何,这是最简单的方式,但它有问题:
因此,更好的解决方案是为每个客户端提供队列,并为读取器线程提供服务该队列的编写器线程。 (然后你可以通过各种方式对其进行扩展 - 对队列设置限制,以便人们不再试图与远远落后的人交谈,等等。)
正如Anzel指出的那样,除了每个客户端使用一个(或两个)线程之外,还有一种不同的设计服务器的方式:使用多路复用所有客户端的reactor '事件。
Python 3.x有一些很棒的内置库,但2.7只有笨重的和过时的asyncore
/ asynchat
和低级select
。
正如Anzel所说,Python SocketServer: sending to multiple clients使用asyncore
得到答案,值得一读。但我实际上不会使用它。如果你想在Python 2.x中编写一个基于反应堆的服务器,我要么使用更好的第三方框架,比如Twisted,要么找到或写一个直接位于select
的非常简单的框架。 }。