面向对象epoll
# -*- coding: utf-8 -*- import socket import selectors import re import sys HTML_ROOT = "./static" WSGI_ROOT = "./wsgipy" class Httpserver: def __init__(self): self.server = socket.socket() self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 释放端口 self.epoll_selector = selectors.EpollSelector() def bind(self, port): self.server.bind(('', port)) def start(self): self.server.listen(1000)
# self.server为套接字对象(也是server_conn的参数), self.server_conn为方法(必须由一个参数接收该对象) self.epoll_selector.register(self.server, selectors.EVENT_READ, self.server_conn) while True: events = self.epoll_selector.select() for event, n in events: file_obj = event.fileobj callback = event.data callback(file_obj) def server_conn(self, server): conn, addr = server.accept() self.epoll_selector.register(conn, selectors.EVENT_READ, self.server_recv) def server_recv(self, conn): recv_data = conn.recv(1024) if recv_data: response_data_line = recv_data.splitlines()[0] file_path = re.match(r'\w+ +(/[^ ]*) ', response_data_line.decode()).groups()[0] # if file_path == '/favicon.ico': # response_header = 'HTTP/1.1 200 OK\r\n' # response_header += "Content-Type: text/image\r\n" print(file_path)
# 动态执行py文件 if file_path.endswith('.py'): try: module = __import__(file_path[1:-3]) except Exception: response_header = 'HTTP/1.1 404 NotFound\r\n' send_html_content = 'no cun zai' else: send_html_content = module.application({}, self.start_response) response_header = self.response_header else: if file_path == '/': file_path = '/index.html' file_path = HTML_ROOT + file_path send_html_content = self.read_file(file_path) if not send_html_content: response_header = 'HTTP/1.1 404 NotFound\r\n' send_html_content = 'This page is not found.' else: response_header = 'HTTP/1.1 200 OK\r\n' response_server_version = 'super: 1.1\r\n' send_data = response_header + response_server_version + '\r\n' + send_html_content conn.send(send_data.encode()) self.epoll_selector.unregister(conn) conn.close() def start_response(self, status, headers): response_header = "HTTP/1.1" + status + "\r\n" + "super: 1.1\r\n" for i in headers: response_header += "%s: %s\r\n" % i self.response_header = response_header def read_file(self, file_path): try: with open(file_path, 'rb') as f: content = f.read() except Exception: return False print(file_path) return content.decode() if __name__ == '__main__': # sys.path.insert(1, HTML_ROOT) # sys.path.insert(1, WSGI_ROOT) server = Httpserver() server.bind(8000) server.start()