Если вам нужно отправить сообщение всем клиентам, вам необходимо каким-то образом сохранить коллекцию всех клиентов. Например:
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
.
Как говорит Анзель, Python SocketServer: sending to multiple clients имеет ответ, используя asyncore
, что стоит прочитать. Но я бы на самом деле не использовал это. Если вы хотите написать сервер на базе реакторов в Python 2.x, я бы использовал лучшую стороннюю структуру, например Twisted, или нашел или написал очень простой, который находится непосредственно на select
.
Не пытайтесь опубликовать код Python как фрагмент кода запуска; что работает только для JS/HTML/CSS. (На этот раз я отредактировал его.) – abarnert
Как примечание, ваш код имеет сочетание вкладок и пробелов. Это действительно плохая идея; это может легко привести к тому, что Python не понимает структуру блока так же, как вы или другой человек. Вы должны рассмотреть возможность переключения на редактор, который поможет вам избежать этой проблемы, а также запустить скрипт с помощью 'python -t' или' python -tt', чтобы убедиться, что вы его исправили и не воссоздали. – abarnert
Пожалуйста, взгляните на этот SO принятый ответ [Python SocketServer: отправка нескольким клиентам?] (Http://stackoverflow.com/questions/3670127/python-socketserver-sending-to-multiple-clients), возможно, это точно что вы ищете, особенно со всеми предложенными пунктами @abarnert, которые рассматриваются в небольшом примере реализации. – Anzel