套接字与线程间通信
我正在使用多线程的TCP服务器。每个客户端的连接都是通过单独的线程来处理的。我想通过socket的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()
2 个回答
1
你可以把你的线程变成对象(如果有的话),让它们变得可以“迭代”,然后你可以写一个“广播”函数,这个函数会遍历你的线程,利用它们的套接字来发送信息。
如果你没有每个线程对应一个对象,你也可以简单地用一个套接字的列表,做差不多的事情。
确保根据你的需求正确使用锁(可以是对所有套接字使用锁,或者是对每个单独的套接字使用锁)。
0
TCP套接字是两个端点之一。在TCP中没有“广播”这个概念。如果你想把一条消息发送给所有的客户端,你必须一个一个地发送给他们。
如果你为所有的客户端对象使用一个合适的容器,那么你只需要遍历这个容器,把消息发送给每一个客户端就可以了。