0%

Python实现多线程 web静态服务器

今天做了一个题目,用Python实现多线程 web静态服务器,返回固定的页面。

题目

1
2
3
实现一个 多线程 web静态服务器,返回固定的页面。     
1. 使用面向对象实现
2. 端口 命令行获取

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

import sys
import socket
import threading

# readme:python3 xxx.python 运行,记得放置static对应的index.html

# 判断输入命令行是否合法
# 合法格式:python3 xxx.python 端口号
def check(param):
if len(param) != 2:
return False
if not param[1].isdigit():
return False
return True


# 从系统参数中获取端口号参数
# 如果参数非法,默认采用8089。
def get_port_param(param):
port = 8089
if check(param):
port = param[1]
else:
print("命令行不符合:【python3 xxx.python 端口号】,采用默认端口号: 8089")
return int(port)


# 拼接返回数据response
def build_response(status_code, file_data):
response_line = "HTTP/1.1 " + status_code + "\r\n"
response_header = "Server: PWS/1.0\r\n"
response_body = file_data
# 拼装response
response = (response_line + response_header + "\r\n").encode("utf-8") + response_body
return response


class HttpWebServer(object):
def __init__(self, port):
# 创建TCP套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设置端口号复用
tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 绑定端口号
tcp_server_socket.bind(("", port))
# 设置监听
tcp_server_socket.listen(128)
# tcp服务器的套接字作为web服务器对象的属性赋值
self.tcp_server_socket = tcp_server_socket

# 处理客户端请求
@staticmethod
def handle_client_request(new_socket):
# 接收客户端请求信息
recv_data = new_socket.recv(4096)
# 判断接收是否结束
if len(recv_data) == 0:
new_socket.close()
return

# 对二进制数据进行解码
recv_content = recv_data.decode("utf-8")
print(recv_content)

# 对数据按照空格进行分割
request_list = recv_content.split(" ", maxsplit=2)
# 获取请求的资源路径
request_path = request_list[1]
print(request_path)

# 判断请求是否是根目录·,如果是,直接返回
if request_path == "/":
request_path = "/index.html"

try:
with open("static" + request_path, "rb") as file:
file_data = file.read()

# 发送给浏览器的响应报文
response = build_response("200 OK", file_data)
new_socket.send(response)
except Exception as e:
# 404页面
with open("static/error.html", "rb") as file:
file_data = file.read()

# 拼接返回数据response
response = build_response("404 Not Found", file_data)
# 发送给浏览器的响应报文
new_socket.send(response)
finally:
new_socket.close()

# 启动服务器
def start(self):
# 循环等待
while True:
# 等待请求
new_socket, ip_port = self.tcp_server_socket.accept()
# 建立连接
sub_thread = threading.Thread(target=self.handle_client_request, args=(new_socket,))
# 设置为守护主线程
sub_thread.setDaemon(True)
# 启动子线程执行对应的任务
sub_thread.start()


def main():
# 1. 命令行参数获取
port = get_port_param(sys.argv);
# 2. 服务器启动
sever = HttpWebServer(port);
sever.start()
print("启动完毕!")


if __name__ == '__main__':
main()
觉得不错?