python全栈第二十一天 HTTP

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()

需求实现多任务版本

猜你喜欢

转载自blog.csdn.net/qq_41179365/article/details/110930832
今日推荐