1 Star 0 Fork 0

Levi0321/http_server

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
web_server.py 3.15 KB
一键复制 编辑 原始数据 按行查看 历史
Levi0321 提交于 2023-03-01 13:59 . add server
"""
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() # 允许浏览器连接
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Python
1
https://gitee.com/levi0321/http_server.git
git@gitee.com:levi0321/http_server.git
levi0321
http_server
http_server
master

搜索帮助