Python 使用puthon3套接字的非常简单的单线程无阻塞web服务器
读过: 我编写了这个python代码来运行我的家庭中央供暖系统,它只返回一个网页,该网页由代码生成,带有3个基本按钮,用于“打开和计时”我的供暖系统,并且一次不会有多个或多个连接,我不想实现一个完整的web服务器 到目前为止,我已经启动并运行了以下类的创建实例。 如果有人有任何输入,我当前关心的是检查连接的套接字的活动状态。 这个块,我称之为socket。_closedon the socket,它似乎工作得很好,但是socket。_closed有一个下划线,我对python的有限知识告诉我,以下划线开头的东西是内部的,不应该被调用,有没有更好的方法来实现这一点,或者任何类Python 使用puthon3套接字的非常简单的单线程无阻塞web服务器,python,sockets,Python,Sockets,读过: 我编写了这个python代码来运行我的家庭中央供暖系统,它只返回一个网页,该网页由代码生成,带有3个基本按钮,用于“打开和计时”我的供暖系统,并且一次不会有多个或多个连接,我不想实现一个完整的web服务器 到目前为止,我已经启动并运行了以下类的创建实例。 如果有人有任何输入,我当前关心的是检查连接的套接字的活动状态。 这个块,我称之为socket。_closedon the socket,它似乎工作得很好,但是socket。_closed有一个下划线,我对python的有限知识告诉我
r = list(range(0, len(self.sockets)))
for i in r:
if self.sockets[i]._closed:
del self.sockets[i:i+1] # remove closed socket from collection
del r[i:i+1] # remove corresponding index from rage
完整的工人阶级如下:
class WebServer():
def __init__(self, program, port):
self.program = program
self.port = port
self.serverSocket = None
def dispose(self):
if self.serverSocket != None:
print("WebServer disposing")
for i in range(0, len(self.sockets)):
try:
self.sockets[i].shutdown(0)
self.sockets[i].close()
except:
traceback.print_stack()
try:
self.serverSocket.shutdown(0)
self.serverSocket.close()
except:
traceback.print_stack()
self.sockets.clear()
self.sockets = None
self.serverSocket = None
print("WebServer disposed")
def update(self):
if self.serverSocket == None:
print("WebServer initializing")
try:
self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.serverSocket.settimeout(1) # timeout for listening
self.serverSocket.bind(('', self.port))
self.serverSocket.listen(5)
self.serverSocket.setblocking(0)
self.sockets = [] # list to hold client sockets
print("WebServer bound to port " + str(self.port))
except:
self.serverSocket = None
traceback.print_stack()
return
# accept new sockets
clientSocket = None
try:
(clientSocket, clientAddress) = self.serverSocket.accept()
except BlockingIOError: pass
if clientSocket != None:
print("Connection from " + clientAddress[0] + ":" + str(clientAddress[1]))
clientSocket.setblocking(0)
self.sockets.append(clientSocket)
# remove closed sockets from list
#self.sockets[:] = [x for x in self.sockets if not x._closed]
r = list(range(0, len(self.sockets)))
for i in r:
if self.sockets[i]._closed:
del self.sockets[i:i+1] # remove closed socket from collection
del r[i:i+1] # remove corresponding index from rage
# respond to active sockets
for i in range(0, len(self.sockets)):
#print("Socket" + str(i))
#print(dir(self.sockets[i]))
recData = None
try: recData = self.sockets[i].recv(1024).strip()
except BlockingIOError:
hostname = self.sockets[i].getpeername()
print("BlockingIOError: " + str(hostname[0] + ":" + str(hostname[1])) + " ")
except BrokenPipeError:
hostname = self.sockets[i].getpeername()
print("BrokenPipeError: " + str(hostname[0] + ":" + str(hostname[1])) + " ")
if recData != None:
lines = recData.decode().splitlines()
if len(lines) > 0:
index = -1
for i2 in range(len(lines)):
if index == -1 and lines[i2] == "":
index = i2+1
break
header = ""
content = ""
if index == -1:
header = "\n".join(lines)
else:
headerList = []
for i2 in range(0, index-1):
headerList.append(lines[i2])
header = "\n".join(headerList)
contentList = []
for i2 in range(index, len(lines)):
contentList.append(lines[i2])
content = "\n".join(contentList)
# split the first line and extract the method, path and args
line1 = lines[0].split(" ")
method = line1[0]
line1_1 = line1[1].split("?", 1)
path = line1_1[0]
args = line1_1[1] if len(line1_1) > 1 else ""
# call the method to generate the responce
(header, content) = self.respond_event(header, method, path, args, content)
responce = header + "\nContent-Length: " + str(len(content)) + "\nContent-Type: text/html\n" + "Connection: Closed\n\n" + content
self.sockets[i].sendall((responce).encode())
hostname = self.sockets[i].getpeername()
print("Respond to " + str(hostname[0] + ":" + str(hostname[1])) + " " + header)
self.sockets[i].close()
def respond_event(self, header, method, path, args, content):
# this method should be overridden to generate the response else it just returns page not found
title = "Page Not Found"
body = "Page Not Found"
content = "<!DOCTYPE html>\n<html>\n<head>\n<title>" + title + "</title>\n</head>\n\n<body>\n" + body + "\n</body>\n</html>"
return ["HTTP/1.1 404 NOT FOUND", content]
self.webServer = WebServer(self, 80)
#self.webServer.respond_event = self.webServer_respond # attach response generator
while True:
self.webServer.update()
# ... do other stuff.