python - 套接字和线程间的内部通信

标签 python multithreading networking

我正在使用多线程 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()

最佳答案

您可以创建线程对象(如果有)iterable然后您创建一个“广播”函数,该函数仅循环访问您的线程并使用它们的套接字发送信息。

或者,如果每个线程没有一个对象,您始终可以只拥有一个套接字列表并执行几乎相同的操作。

确保根据您的需要正确使用锁(对于所有套接字或每个单独的套接字)

关于python - 套接字和线程间的内部通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6381201/

相关文章:

web-services - 如何使用网络安全组仅允许我的 Web 应用程序与我的 Web 服务通信

python - boto库如何读取飞行状态消息并删除

python - 有没有办法阻止 __init__ 方法的执行?

python - Tkinter 按钮在我的 Mac 上不显示文本,尽管代码在其他计算机上有效

c++ - memory_order_relaxed 是否尊重同一线程内的数据依赖性?

networking - 当多台计算机具有相同的 IP 地址时,如何以编程方式连接到其中一台?

python - 架构 - 能够在 Django 中更改电子邮件地址(主要用户 ID)

java - modelAndView返回后执行任务

java - 当ExecutorService ThreadFactory返回null而不是thead时如何处理

networking - DNS 解析是否适用于使用非 headless 服务的 PetSet?