python手写一款静态web服务器

107 阅读1分钟

利用多线程和socket手写一款简易的静态web服务器,了解其中的原理,原来web服务器没有复杂和神秘

在.py文件的同级目录准备web静态文件的结构,如图所示

image.png

web.py

import os
import socket
import threading


def handle_requst_page(new_client,):
    # 4. 接受请求
    try:
        recv_data = new_client.recv(4096)
        recv_content = recv_data.decode('utf-8')
        resv_page = recv_content.split(" ", 2)
        if len(resv_page) >=2:
            page_index = resv_page[1]
            # 发送的数据为空时  /
            # 当传入地址为空时,默认index地址
            if page_index == '/':
                page_index = '/index.html'
            # 5.发送请求
            """
             HTTP/1.1 200 OK # 报文行
             Server: BWS/1.1  # 报文头
             空格 \r\n
             Response: xxx # 报文体
            """
            path = "web/static" + page_index
            if not os.path.exists(path):
                print("404")
                path = "web/static/404.html"
            with open(path, 'rb') as file:
                res_content = file.read()
            res_line = "HTTP/1.1 200 OK\r\n"
            res_server = "Server: PWS/1.0\r\n"
            response = (res_line +
                        res_server +
                        "\r\n").encode("utf-8") + res_content
            new_client.send(response)
    except ValueError:
        print("错误信息:",ValueError)
    finally:
        new_client.close()

#  tcp socket 报文处理
if __name__ == '__main__':
    # 创建套接字,处理socket
    # AF_INET IPV4,SOCK_STREAM TCP的协议
    tcp_server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 设置端口复用
    tcp_server_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,True)
    # 1.绑定单口
    tcp_server_socket.bind(("",9000))
    # 2. 设置监听
    tcp_server_socket.listen(128)
    while True:
        # 3.等待客户端请求
        new_client, ip_port =tcp_server_socket.accept()
        print("链接的客户端为",ip_port)
        # 创建线程处理多个链接,并设置主线程守护daemon=True
        sub_thread = threading.Thread(target=handle_requst_page,args=(new_client,),daemon=True)
        # sub_thread.setDaemon(True)  #设置主线程守护的第二种方法
        sub_thread.start()

        # 6.关闭套件字
        # tcp_server_socket.close()

下一篇,将利用面相对象的方式加以改造~~