Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python多线程套接字_Python_Multithreading_Sockets - Fatal编程技术网

Python多线程套接字

Python多线程套接字,python,multithreading,sockets,Python,Multithreading,Sockets,根据我的理解,python一次只能运行一个线程,所以如果我要这样做的话 import socket, select from threading import Thread import config class Source(Thread): def __init__(self): self._wait = False self._host = (config.HOST, config.PORT + 1) self._socket =

根据我的理解,python一次只能运行一个线程,所以如果我要这样做的话

import socket, select
from threading import Thread
import config

class Source(Thread):
    def __init__(self):
        self._wait = False
        self._host = (config.HOST, config.PORT + 1)
        self._socket = socket.socket()
        self._socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self._sock = None
        self._connections = []
        self._mount = "None"
        self._writers = []
        self._createServer()
        Thread.__init__(self)

    def _createServer(self):
        self._socket.bind(self._host)
        self._socket.listen(2)
        self._connections.append(self._socket)
        self._audioPackets=[]

    def _addPacket(self, packet):
        self._audioPackets.append(packet)

    def _removePacket(self, packet):
        self._audioPackets.remove(packet)

    def _getPacket(self):
        if len(self._audioPackets) > 0:
            return self._audioPackets[0]
        else:
            return None

    def _sendOK(self, sock):
        sock.send("OK")

    def _sendDenied(self, sock):
        sock.send("DENIED")

    def _sendMount(self, sock):
        sock.send("mount:{0}".format(self._mount))

    def _sendBufPacket(self, sock, packet):
        packet = "buffer:%s" % packet
        sock.send(packet)

    def recv(self, sock, data):
        data = data.split(":", 1)
        if data[0] == "WAIT": self._wait = True
        elif data[0] == "STOP_WAITING": self._wait = False
        elif data[0] == "LOGIN":
            if data[1] == config.SOURCE_AUTH:
                self._source = sock
                self._sendOK(sock)
            else:
                self._sendClose(sock)
        elif data[0] == "MOUNT":
            if self._source == sock:
                self._mount = data[1]
            else:
                self._sendClose(sock)

        elif data[0] == "CLIENT":
            self._sendMount(sock)
            self._writers.append(sock)


    def _sendCloseAll(self):
        for sock in self._connections:
            sock.send("CLOSE")
            sock.close()

    def _sendClose(self, sock):
        sock.send("CLOSE")
        sock.close()

    def main(self):
        while True:
            rl, wl, xl = select.select(self._connections, self._writers, [], 0.2)
            for sock in rl:
                if sock == self._socket:
                    con, ip = sock.accept()
                    self._connections.append(con)
                else:
                    data = sock.recv(config.BUFFER)
                    if data:
                        self.recv(sock, data)
                    else:
                        if sock in self._writers:
                            self._writers.remove(sock)
                        if sock in self._connections:
                            self._connections.remove(sock)
            for sock in wl:
                packet = self._getPacket()
                if packet != None:
                    self._sendBufPacket(sock, packet)

    def run(self):
        self.main()

class writeThread(Thread):
      def __init__(self):
          self.running = False

      def make(self, client):
          self.client = client
          self.running = True

      def run(self):
          host = (config.HOST, config.PORT+1)
          sock = socket.socket()
          sock.connect(host)
          sock.send("CLIENT")
          sock.send("MOUNT:mountpoint")
          while self.running:
              data = sock.recv(config.BUFFER)
              if data:
                  data = data.split(":", 1)
                  if data[0] == "buffer":
                     self.client.send(data[1])
                  elif data[0] == "CLOSE":
                       self.client.close()
                       break


if __name__=="__main__":
    source = Source()
    source.start()
    webserver = WebServer()
    webserver.runloop()
如果我需要构建Web服务器部分,我会。但是,我会解释的。
好的,基本上当有人在设置的挂载点下连接到Web时,他们会得到自己的个人线程,然后从
Source()
获取数据并发送给他们。现在假设另一个人连接到挂载点,最后一个客户端和源仍然在运行。考虑到有两个活动线程,是否会阻止新客户机获取源数据?

根据您提出的问题,您对Python中线程工作方式的理解似乎不正确。如果使用正确,线程将不会阻塞:您可以使用Python实例化多个线程。限制在于,由于(GIL),您无法获得线程编程中预期的完全并行性(例如,同时执行,从而减少运行时)。
在您的情况下,这两个线程将一起花费与按顺序执行时相同的时间(尽管实际上不一定如此)。

好的,我已经复制并粘贴了一些Python3代码,这些代码是我为当前正在进行的项目编写的。通过修改,您可以使此代码满足您的目的

代码使用多处理和多线程。出于我的目的,我使用多处理,这样套接字将在一个处理器上运行,并且我可以在另一个处理器上运行GUI程序。如果愿意,可以删除多处理器部件。下面的代码运行套接字消息服务器。服务器将一次侦听一个客户端。客户端连接后,将启动一个新线程来处理服务器和每个客户端之间的所有通信。然后服务器将继续搜索客户端。然而,目前服务器只监听从每个客户端发送的数据,然后将其打印到终端。只需少量工作,就可以修改我的代码,将信息从服务器分别发送到每个客户机

import multiprocessing
import threading
from threading import Thread

class ThreadedServer(object):

    def __init__(self, host, port):
    self.host = host
    self.port = port
    self.sock = socket(AF_INET, SOCK_STREAM)
    self.sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    self.sock.bind((self.host, self.port))

    def listen(self):    
        self.sock.listen(3) #Allow 3 Clients to connect to this server
        while True:
            #The program will search for one client at a time
            print("Searching for Client")
            client, address = self.sock.accept()
            print(address, " is connected")
            #client.settimeout(60)

            #Once a client has been found, start a individual client thread
            d = threading.Thread(target = self.listenToClient, args=(client, address))
            d.daemon = True
            d.start()

def listenToClient(self, client, address):
    size = 1024
    while True:
        try:
            data = client.recv(size)
            if not data:
                break
            if data:
                print(data)
                #client.send(response)
            else:
                raise error('Client disconnected')
        except:
            client.close()
            return False

def dataSharingHost():
    #Using Sockets to send information between Processes
    #This is the server Function
    #ThreadServer(Host_IP, Port_Number), for LocalHost use '' 
    ThreadedServer('', 8000).listen() 

def Main():
    commServer = multiprocessing.Process(target=dataSharingHost, args=())
    commServer.daemon = True
    commServer.start()

if __name__== '__main__':
    Main()

公平地说,我的代码是从。这些视频中介绍了客户端代码。我认为第三个视频涵盖了多个客户端连接。

客户端,address=self.sock.accept()
如果另一个客户端连接或客户端重新连接,这不会引发错误吗?我一次连接3个客户端没有问题。self.sock.listen(3)将服务器配置为同时接受3个客户端。事实证明,“address”变量实际上包含两条信息。第一部分是客户机的IP地址,如果运行此代码,该地址应为127.0.0.1。第二条信息是“地址”变量,它是每个连接的客户端的唯一ID。因此,每个客户端都将获得自己的ID。目前,此代码不够复杂,无法允许客户端重新连接。那一定是我在晚些时候做的。