插座&线程间的通信

时间:2011-06-17 04:02:51

标签: python multithreading networking

我正在使用多线程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 个答案:

答案 0 :(得分:1)

您可以创建线程对象(如果有的话)iterable并创建一个“广播”函数,它只是遍历您的线程并使用它们的套接字发送信息。

或者如果你没有每个线程的对象,你总是可以只有一个套接字列表,并做几乎相同的事情。

确保根据需要正确使用锁(适用于所有套接字或每个插槽)

答案 1 :(得分:0)

TCP套接字是两个端点之一。 TCP中没有“广播”这样的东西。如果您想向所有客户发送一条消息,则必须将它们分别发送给每个客户。

如果您为所有客户端对象使用合适的容器,那么只需对此进行迭代即可,将消息发送给每个客户端。