代码拉取完成,页面将自动刷新
"""
web server
"""
from socket import *
from select import *
class Handle():
def __init__(self, ep, map, html):
self.html = html # 存储网页路径
self._ep = ep
self.map = map
def close(self, fd):
self._ep.unregister(fd) # 不再关注
self.map[fd].close()
del self.map[fd] # 维护字典
# 处理数据收发
def handle(self, fd):
# 浏览器的http请求
request = self.map[fd].recv(1024).decode()
if not request:
self.close(fd)
return
info = request.split(' ')[1]
print("请求内容:", info)
self._send_html(fd, info)
self.close(fd) # 每个内容访问后主动断开
def _response(self, status, content: bytes):
response = "HTTP/1.1 %s\r\n" % status
response += "Content-Type:text/html\r\n"
response += "\r\n"
response = response.encode() + content
return response
# 组织响应并发送
def _send_html(self, fd, info):
if info == '/':
# 主页比较特殊 --》 index.html
filename = self.html + "/index.html"
else:
filename = self.html + info
try:
fr = open(filename, 'rb')
except:
with open(self.html + "/404.html", 'rb') as fr:
data = fr.read()
response = self._response("404 Not Found", data)
else:
response = self._response("200 OK", fr.read())
finally:
# 发送响应
self.map[fd].send(response)
# 搭建网络结构
class WebServer:
def __init__(self, host='', port=0, html=None):
self.host = host
self.port = port
self.address = (host, port)
self.html = html # 网页位置
self._ep = epoll()
self.map = {} # 存储文件描述符和对象的对应关系
self.sock = self._create_socket()
self._handle = Handle(self._ep, self.map, html)
def _create_socket(self):
sock = socket()
sock.bind(self.address)
sock.setblocking(False) # 非阻塞
return sock
# 处理客户端连接
def _connect(self, fd):
# 监听套接字对象就绪 :连接客户端
conn, addr = self.map[fd].accept()
conn.setblocking(False)
# 关注conn读
self._ep.register(conn, EPOLLIN)
self.map[conn.fileno()] = conn # 维护字典
# 主体服务
def serve_forever(self):
self.sock.listen(5)
self._ep.register(self.sock, EPOLLIN)
self.map[self.sock.fileno()] = self.sock
print("Listen the port %d" % self.port)
# 循环监控IO对象的发生
while True:
events = self._ep.poll() # [(fileno,event),()]
for fd, event in events:
if fd == self.sock.fileno():
self._connect(fd)
else:
try:
self._handle.handle(fd)
except:
pass
if __name__ == '__main__':
httpd = WebServer(host="0.0.0.0", port=8000, html="./static")
httpd.serve_forever() # 允许浏览器连接
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。