用户:
tq_xyy查看:0 回复:1 评论:0 创建时间:2020-06-07T19:14:29
最近写服务器,解析请求报文时很麻烦,用的是正则表达式,很累,有人可以告诉我有什么好的方法吗?
代码:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import sys
import socket
import re
import datetime
from os.path import getctime
from multiprocessing import Process
now = lambda:datetime.datetime.now().strftime("[%H-%M-%S]")
# 设置静态文件根目录
H喵L_ROOT_DIR = "."
LINES_SEP = bytes("\r\n", "utf-8")
class HTTPServer(object):
def __init__(self):
print(now(),"创建服务器")
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
def start(self):
print(now(),"开始运行服务器,按 Ctrl+C 退出")
try:
self.server_socket.listen(128)
while True:
client_socket, client_address = self.server_socket.accept()
print(now(),"连接 %s:%s" % client_address)
handle_client_process = Process(target=self.handle_client, args=(client_socket,))
handle_client_process.start()
client_socket.close()
except KeyboardInterrupt:
print(now(),"服务器已停止运行")
def handle_client(self, client_socket):
"""
处理客户端请求
"""
# 获取客户端请求数据
request_data = client_socket.recv(4096)
request_lines = request_data.splitlines()
# 解析请求报文
if len(request_lines) == 0:
client_socket.close()
print(now(),"Error:","空请求")
return "error"
request_start_line = request_lines[0]
# 提取用户请求的文件名
file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1)
if "/" == file_name:
file_name = "/index.html"
# 打开文件,读取内容
try:
file = open(H喵L_ROOT_DIR + file_name, "rb")
except IOError:
with open(H喵L_ROOT_DIR + "/error/404.html","rb") as file:
file_data = file.read()
response_start_line = "HTTP/1.1 404 Not Found\r\n".encode("utf-8")
response_headers = "Server: Python\r\n".encode("utf-8")
response_body = file_data
print(now(),"HTTP/1.1 404 Not Found " + file_name)
else:
file_data = file.read()
file.close()
# 构造响应数据
response_start_line = "HTTP/1.1 200 OK\r\n".encode("utf-8")
response_headers = "Server: Python \r\n".encode("utf-8")
response_body = file_data
print(now(),"HTTP/1.1 200 OK " + file_name)
response = response_start_line + response_headers + LINES_SEP + response_body
# 向客户端返回响应数据
client_socket.send(response)
# 关闭客户端连接
client_socket.close()
def bind(self, port):
print(now(),"监听 {} 端口".format(port))
self.server_socket.bind(("", port))
def main():
http_server = HTTPServer()
http_server.bind(80)
http_server.start()
if __name__ == "__main__":
main()