python开发-静态web服务器

python开发-静态web服务器(程序)

可以为发出请求的浏览器提供静态文档的程序

python自带的静态Web服务器

搭建Python自带的静态Web服务器使用 python3-m http.server 端口号(默认8000)

-m选项说明:
-m表示运行包里面的模块,执行这个命令的时候,需要进入你自己指定静态文件的目录,然后通过浏览器就能访问对应的html文件了,这样一个静态的web服务器就搭建好了。

开发自己的静态web服务器

任意请求返回同样的内容

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
import socket


if __name__ == '__main__':
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(("",9000))
tcp_server_socket.listen(128)
while True:
new_socket,client = tcp_server_socket.accept()
# 每一次接收4kb的数据,其实浏览器get请求每次也最多发送4kb左右的数据
recv_data = new_socket.recv(4096)
print(recv_data)
with open(r"static\index.html",encoding="utf-8") as f:
send_data = f.read()
# 响应行
response_line = "HTTP/1.1 200 OK"+"\r\n"
# 响应头
response_header = "PWS/1.0"+"\r\n"
# 响应体,空行在下面有加入
response_body = send_data
# 封装成http数据格式,并且转换成二进制
response_data = (response_line+response_header+"\r\n"+response_body).encode(encoding="utf-8")
new_socket.send(response_data)

new_socket.close()

返回对应页面

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



if __name__ == '__main__':
import socket
import os
os.chdir(os.path.dirname(os.path.abspath(__file__)))
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(("",9000))
tcp_server_socket.listen(128)
while True:
new_socket,client = tcp_server_socket.accept()
# 每一次接收4kb的数据,其实浏览器get请求每次也最多发送4kb左右的数据
recv_data = new_socket.recv(4096)
# b'GET / HTTP/1.1\r\nHost: localhost:9000\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nsec-ch-ua: "Chromium";v="148", "Google Chrome";v="148", "Not/A)Brand";v="99"\r\nsec-ch-ua-mobile: ?0\r\nsec-ch-ua-platform: "Windows"\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\r\nSec-Fetch-Site: none\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-User: ?1\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br, zstd\r\nAccept-Language: zh-CN,zh;q=0.9\r\ndnt: 1\r\nsec-gpc: 1\r\n\r\n'
print(recv_data)
resource_path = recv_data.decode(encoding="utf-8").split(" ",maxsplit=2)[1]
# 直接请求域名:端口 时资源路径默认是/
if resource_path == "/":
resource_path = "/index.html"
print(resource_path)
# 页面不存在时返回404页面
# os.path.exists("static/404.html")
try:
# 涉及到图片读取,为了通用,所有这里使用二进制r读取
with open(rf"static{resource_path}",mode='rb') as f:
send_data = f.read()
except Exception:
# with open支持\和/
with open(rf"static/404.html",mode='rb') as f:
send_data = f.read()
# 响应行
response_line = "HTTP/1.1 404 Not Found"+"\r\n"
# 响应头
response_header = "PWS/1.0"+"\r\n"
# 响应体,空行在下面有加入
response_body = send_data
# 封装成http数据格式,并且转换成二进制
response_data = (response_line+response_header+"\r\n").encode(encoding="utf-8")+response_body
new_socket.send(response_data)
else:
# 响应行
response_line = "HTTP/1.1 200 OK"+"\r\n"
# 响应头
response_header = "PWS/1.0"+"\r\n"
# 响应体,空行在下面有加入
response_body = send_data
# 封装成http数据格式,并且转换成二进制
response_data = (response_line+response_header+"\r\n").encode(encoding="utf-8")+response_body
new_socket.send(response_data)
finally:
new_socket.close()

静态web服务器-多任务版

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
import socket       
import os
import threading


def handle_client_request(new_socket,client):
# 每一次接收4kb的数据,其实浏览器get请求每次也最多发送4kb左右的数据
recv_data = new_socket.recv(4096)
# b'GET / HTTP/1.1\r\nHost: localhost:9000\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nsec-ch-ua: "Chromium";v="148", "Google Chrome";v="148", "Not/A)Brand";v="99"\r\nsec-ch-ua-mobile: ?0\r\nsec-ch-ua-platform: "Windows"\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\r\nSec-Fetch-Site: none\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-User: ?1\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br, zstd\r\nAccept-Language: zh-CN,zh;q=0.9\r\ndnt: 1\r\nsec-gpc: 1\r\n\r\n'
print(client)
print(recv_data)
resource_path = recv_data.decode(encoding="utf-8").split(" ",maxsplit=2)[1]
# 直接请求域名:端口 时资源路径默认是/
if resource_path == "/":
resource_path = "/index.html"
print(resource_path)
# 页面不存在时返回404页面
# os.path.exists("static/404.html")
try:
# 涉及到图片读取,为了通用,所有这里使用二进制r读取
with open(rf"static{resource_path}",mode='rb') as f:
send_data = f.read()
except Exception:
# with open支持\和/
with open(rf"static/404.html",mode='rb') as f:
send_data = f.read()
# 响应行
response_line = "HTTP/1.1 404 Not Found"+"\r\n"
# 响应头
response_header = "PWS/1.0"+"\r\n"
# 响应体,空行在下面有加入
response_body = send_data
# 封装成http数据格式,并且转换成二进制
response_data = (response_line+response_header+"\r\n").encode(encoding="utf-8")+response_body
new_socket.send(response_data)
else:
# 响应行
response_line = "HTTP/1.1 200 OK"+"\r\n"
# 响应头
response_header = "PWS/1.0"+"\r\n"
# 响应体,空行在下面有加入
response_body = send_data
# 封装成http数据格式,并且转换成二进制
response_data = (response_line+response_header+"\r\n").encode(encoding="utf-8")+response_body
new_socket.send(response_data)
finally:
new_socket.close()

def main():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
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(("",9000))
tcp_server_socket.listen(128)
while True:
new_socket,client = tcp_server_socket.accept()
t = threading.Thread(target=handle_client_request,args=(new_socket,client))
t.daemon = True
t.start()


if __name__ == '__main__':
main()

静态web服务器-面向对象开发

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
import socket       
import os
import threading

class HttpWebServer():
def __init__(self):
os.chdir(os.path.dirname(os.path.abspath(__file__)))
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(("",9000))
tcp_server_socket.listen(128)
self.tcp_server_socket = tcp_server_socket

# 没有使用到实例或者类相关的
@staticmethod
def handle_client_request(new_socket,client):
# 每一次接收4kb的数据,其实浏览器get请求每次也最多发送4kb左右的数据
recv_data = new_socket.recv(4096)
# b'GET / HTTP/1.1\r\nHost: localhost:9000\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nsec-ch-ua: "Chromium";v="148", "Google Chrome";v="148", "Not/A)Brand";v="99"\r\nsec-ch-ua-mobile: ?0\r\nsec-ch-ua-platform: "Windows"\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\r\nSec-Fetch-Site: none\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-User: ?1\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br, zstd\r\nAccept-Language: zh-CN,zh;q=0.9\r\ndnt: 1\r\nsec-gpc: 1\r\n\r\n'
print(client)
print(recv_data)
resource_path = recv_data.decode(encoding="utf-8").split(" ",maxsplit=2)[1]
# 直接请求域名:端口 时资源路径默认是/
if resource_path == "/":
resource_path = "/index.html"
print(resource_path)
# 页面不存在时返回404页面
# os.path.exists("static/404.html")
try:
# 涉及到图片读取,为了通用,所有这里使用二进制r读取
with open(rf"static{resource_path}",mode='rb') as f:
send_data = f.read()
except Exception:
# with open支持\和/
with open(rf"static/404.html",mode='rb') as f:
send_data = f.read()
# 响应行
response_line = "HTTP/1.1 404 Not Found"+"\r\n"
# 响应头
response_header = "PWS/1.0"+"\r\n"
# 响应体,空行在下面有加入
response_body = send_data
# 封装成http数据格式,并且转换成二进制
response_data = (response_line+response_header+"\r\n").encode(encoding="utf-8")+response_body
new_socket.send(response_data)
else:
# 响应行
response_line = "HTTP/1.1 200 OK"+"\r\n"
# 响应头
response_header = "PWS/1.0"+"\r\n"
# 响应体,空行在下面有加入
response_body = send_data
# 封装成http数据格式,并且转换成二进制
response_data = (response_line+response_header+"\r\n").encode(encoding="utf-8")+response_body
new_socket.send(response_data)
finally:
new_socket.close()

def main(self):
while True:
new_socket,client = self.tcp_server_socket.accept()
t = threading.Thread(target=self.handle_client_request,args=(new_socket,client))
t.daemon = True
t.start()


if __name__ == '__main__':
httpwebserver = HttpWebServer()
httpwebserver.main()

静态web服务器-命令行动态设置端口