Я использую многопоточный TCP-сервер. Каждый сокет создается как отдельный поток для каждого клиента. Я хотел бы отправить данные всем клиентам с помощью метода send() сокета. Проблема, с которой я столкнулся, заключается в том, что она отправляет данные в текущий поток (из которого он был получен).
Я не мог найти хорошую документацию для межпоточной связи для Python.
Любое решение моей проблемы, чтобы я мог отправлять данные всем клиентам.
Спасибо.
#!/usr/bin/env python
"""
A server with multithreading to handle multiple clients.
"""
import select
import socket
import sys
import threading
import logging
import datetime
class Server:
def __init__(self):
self.host = ''
self.port = 25000
self.backlog = 5
self.size = 1024
self.server = None
def open_socket(self):
try:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host,self.port))
self.server.listen(5)
lc.append(self.server)
except socket.error, (value,message):
if self.server:
self.server.close()
print "Could not open socket: " + message
sys.exit(1)
def run(self):
self.open_socket()
input = [self.server,sys.stdin]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == self.server:
c = Client(self.server.accept())
c.start()
threads.append(c)
# close all threads
self.server.close()
for c in threads:
c.join()
class Client(threading.Thread):
def __init__(self,(client,address)):
threading.Thread.__init__(self)
self.client = client
self.address = address
self.size = 1024
dc[address[0]]=client#address[1]
logging.info('%s added successfully...',address[0])
def run(self):
running = 1
print dc
while running:
data = str(self.client.recv(self.size))
#print dc
if data.strip() == '0x01':
sendtoAll()
elif data.strip() == '0x02':
self.client.send("version"+data)
elif data.strip() == '0x03':#return current time
print datetime.datetime.now()
self.client.send(str(datetime.datetime.now()))
else:
self.client.send("empty")
#self.client.close()
#running = 0
def sendtoAll():
for i, sock in dc.items():
print "Address:Sockets = ", i,sock
try:
print "sending to %s by Thread "%i
sock.send("data"+str(threading.current_thread().getName()))
except socket.error,e:
print "error socket %s\n" % e
sock.close()
del lc[i]
if __name__ == "__main__":
dc={} #dict to store ip-address:scokets pair
lc=[] #tuples to store all sockets
threads=[] #holds threads
logging.basicConfig(level=logging.INFO)
logging.info('Starting Server Object...')
s = Server()
s.run()
И код клиента
import socket
import sys
host = '192.168.1.4'
port = 25000
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host,port))
sys.stdout.write('%')
while 1:
# read from keyboard
line = sys.stdin.readline()
if line == '\n':
break
s.send(line)
data = s.recv(size)
sys.stdout.write(data)
sys.stdout.write('\n%')
s.close()
Сокет TCP является одной из двух конечных точек. В TCP нет такой вещи, как "трансляция". Если вы хотите отправить одно сообщение всем своим клиентам, вам придется отправить его каждому из них по отдельности.
Если вы используете подходящий контейнер для всех ваших клиентских объектов, то shoudl "просто" должен быть повторен по этому поводу, отправив ваше сообщение каждому из них.
Вы можете создавать свои потоковые объекты (если есть) iterable, и вы создаете функцию "трансляции", которая просто перебирает ваши потоки и используйте свои сокеты для отправки информации.
Или, если у вас нет объекта для потоков, вы всегда можете просто иметь список сокетов и делать почти то же самое.
Убедитесь, что вы правильно используете блокировки на основе ваших потребностей (либо для всех сокетов, либо для каждого отдельного сокета)