HTTP
200 正确响应
307 重定向
400 错误请求
404 请求资源再服务器不存在
500 服务器内部源代码出错
python 自带的静态web服务器 python3 -m http.server 9000
开发自己的web服务器
1.编写一个TCP服务器端程序
2.获取浏览器发送的http请求报文数据
3.读取固定页面数据,把页面数据组成http响应报文数据发送给浏览器
4.http响应报文数据发送完成以后,关闭服务于客户端的套接字
(web服务器基于http协议,http是基于tcp协议,tcp是使用socket套接字实现的)
不开线程会形成阻塞等待
返回固定页面
import socket
# 判断是否是主模块的代码
if __name__ == '__main__':
# 创建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(("", 9000))
# 设置监听
tcp_server_socket.listen(128)
while True:
# 等待客户连接请求
new_socket, ip_port = tcp_server_socket.accept()
# 接受客户端请求信息
recv_data = new_socket.recv(4096)
# 打印客户端请求信息
# 给客户端发送数据
with open("index.html", "r") as file:
data_html = file.read()
# 封装Http协议
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
# 响应头
response_header = "Server: PWB/1.0.0\r\n"
# 空行
response_space_line = "\r\n"
# 响应体
response_content = data_html
# 转编码格式发送
response_data = response_line + response_header + response_space_line + response_content
new_socket.send(response_data.encode("utf-8"))
# 关闭客户端套接字
new_socket.close()
返回指定页面
首先创建2个html
这个是123.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>谁玩LOL最菜</title>
</head>
<body>
<h1>还有谁!唯我正义大将!!!</h1>
</body>
</html>
这个是index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>佛山 子初</title>
</head>
<body>
<a>这就是传说中的帅哥吗!!??</a>
</body>
</html>
py代码
import socket
# 判断是否是主模块的代码
if __name__ == '__main__':
# 创建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(("", 9000))
# 设置监听
tcp_server_socket.listen(128)
while True:
# 等待客户连接请求
new_socket, ip_port = tcp_server_socket.accept()
# 接受客户端请求信息
recv_data = new_socket.recv(4096)
print(recv_data)
# 切割所需的动态请求数据
data_list = recv_data.decode("utf-8").split(" ", maxsplit=2)
# 打印客户端请求信息
print(data_list[1])
if data_list[1] == "/":
data_list[1] = "index.html"
# 给客户端发送数据
with open(data_list[1].replace("/", ""), "rb") as file:
data_html = file.read()
# 封装Http协议
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
# 响应头
response_header = "Server: PWB/1.0.0\r\n"
# 空行
response_space_line = "\r\n"
# 响应体
response_content = data_html
# 转编码格式发送
response_data = (response_line + response_header + response_space_line).encode("utf-8") + response_content
new_socket.send(response_data)
# 关闭客户端套接字
new_socket.close()
防止被空数据恶心
import socket
def web_socket():
# 创建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(("", 9000))
# 设置监听
tcp_server_socket.listen(128)
while True:
# 等待客户连接请求
new_socket, ip_port = tcp_server_socket.accept()
# 接受客户端请求信息
recv_data = new_socket.recv(4096)
print(recv_data)
# 切割所需的动态请求数据
data_list = recv_data.decode("utf-8").split(" ", maxsplit=2)
# 防止被请求空数据
if len(data_list) == 0:
new_socket.close()
return
# 打印客户端请求信息
print(data_list[1])
if data_list[1] == "/":
data_list[1] = "index.html"
# 给客户端发送数据
with open(data_list[1].replace("/", ""), "rb") as file:
data_html = file.read()
# 封装Http协议
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
# 响应头
response_header = "Server: PWB/1.0.0\r\n"
# 空行
response_space_line = "\r\n"
# 响应体
response_content = data_html
# 转编码格式发送
response_data = (response_line + response_header + response_space_line).encode("utf-8") + response_content
new_socket.send(response_data)
# 关闭客户端套接字
new_socket.close()
# 判断是否是主模块的代码
if __name__ == '__main__':
web_socket()
如何返回404
先创建一个error.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>404</title>
</head>
<body>
<h1>请求资源不存在!</h1>
</body>
</html>
py
import socket
import os
def web_socket():
# 创建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(("", 9000))
# 设置监听
tcp_server_socket.listen(128)
while True:
# 等待客户连接请求
new_socket, ip_port = tcp_server_socket.accept()
# 接受客户端请求信息
recv_data = new_socket.recv(4096)
print(recv_data)
# 切割所需的动态请求数据
data_list = recv_data.decode("utf-8").split(" ", maxsplit=2)
# 防止被请求空数据
if len(data_list) == 0:
new_socket.close()
return
# 打印客户端请求信息
print(data_list[1])
if data_list[1] == "/":
data_list[1] = "index.html"
file_path = data_list[1].replace("/", "")
# 检查路径是否存在
bool_exists = os.path.exists(file_path)
# 给客户端发送数据
if not bool_exists:
file_path = "error.html"
with open(file_path, "rb") as file:
data_html = file.read()
# 封装Http协议
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
if not bool_exists:
response_line = "HTTP/1.0 404 NOT Found\r\n"
# 响应头
response_header = "Server: PWB/1.0.0\r\n"
# 空行
response_space_line = "\r\n"
# 响应体
response_content = data_html
# 转编码格式发送
response_data = (response_line + response_header + response_space_line).encode("utf-8") + response_content
new_socket.send(response_data)
# 关闭客户端套接字
new_socket.close()
# 判断是否是主模块的代码
if __name__ == '__main__':
web_socket()
多任务版静态web服务器
import socket
import os
import threading
def thread_accept(new_socket, ip_port):
while True:
# 接受客户端请求信息
recv_data = new_socket.recv(4096)
print(recv_data)
# 切割所需的动态请求数据
data_list = recv_data.decode("utf-8").split(" ", maxsplit=2)
# 防止被请求空数据
if len(data_list) == 0:
new_socket.close()
return
# 打印客户端请求信息
print(data_list[1])
if data_list[1] == "/":
data_list[1] = "index.html"
file_path = data_list[1].replace("/", "")
# 检查路径是否存在
bool_exists = os.path.exists(file_path)
# 给客户端发送数据
if not bool_exists:
file_path = "error.html"
with open(file_path, "rb") as file:
data_html = file.read()
# 封装Http协议
# 响应行
response_line = "HTTP/1.0 200 OK\r\n"
if not bool_exists:
response_line = "HTTP/1.0 404 NOT Found\r\n"
# 响应头
response_header = "Server: PWB/1.0.0\r\n"
# 空行
response_space_line = "\r\n"
# 响应体
response_content = data_html
# 转编码格式发送
response_data = (response_line + response_header + response_space_line).encode("utf-8") + response_content
new_socket.send(response_data)
# 关闭客户端套接字
new_socket.close()
# 判断是否是主模块的代码
if __name__ == '__main__':
# 创建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(("", 9000))
# 设置监听
tcp_server_socket.listen(128)
while True:
# 等待客户连接请求
new_socket, ip_port = tcp_server_socket.accept()
thread_sub = threading.Thread(target=thread_accept, args=(new_socket, ip_port))
thread_sub.daemon = True
thread_sub.start()
# 关闭链接
tcp_server_socket.close()
需求实现多任务版本