Python多线程套接字
根据我的理解,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 =
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。目前,此代码不够复杂,无法允许客户端重新连接。那一定是我在晚些时候做的。