Python: 静态 Web 服务器

HTTP Web Server
import socket
import re
import threading
import multiprocessing
import gevent
from gevent import monkey


monkey.patch_all()


def service_client(client_socket):
    """为客户端服务,返回数据"""

    # 接收请求数据
    recv_data = client_socket.recv(1024)
    # 解码请求信息
    recv_msg = recv_data.decode("utf-8")

    # 按行分割
    request_lines = recv_msg.splitlines()

    # 截取文件名
    # 'GET /index.html HTTP/1.1'
    file_name = re.match(r"[^/]+(/[^ ]*)", request_lines[0]).group(1)

    if file_name:
        if file_name == "/":
            file_name = "/index.html"
        print("->" * 10)
        print(file_name)

    # with open("./html" + file_name, "rb") as file_html:
    #     html_content = file_html.read()
    try:
        # 读取文件
        file_html = open("./html" + file_name, "rb")

    except:
        response = "HTTP/1.1 404 NOT FOUND" + "\r\n"
        response += "\r\n"
        response += "<h2> Page Not Found! </h2>"

        # http 数据,给客户端
        client_socket.send(response.encode("utf-8"))

    else:
        # 发送 http 数据,给客户端
        response = "HTTP/1.1 200 OK" + "\r\n"
        response += "\r\n"

        html_content = file_html.read()
        file_html.close()

        # 发送 Header
        client_socket.send(response.encode("utf-8"))
        # 发送 Body
        client_socket.send(html_content)

    # 关闭套接字
    print("### 关闭连接 %d ###" % client_socket.fileno())
    print()
    client_socket.close()


def main():
    # 创建套接字
    tcp_http_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 设置 Socket 选项“重复使用同一地址”
    tcp_http_server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 绑定本机 IP Port
    tcp_http_server.bind(("127.0.0.1", 8088))

    # 监听
    tcp_http_server.listen(128)

    while True:
        # 等待新客户端的连接
        new_socket, client_addr = tcp_http_server.accept()

        # # 服务
        # service_client(new_socket)

        # # 多进程
        # multi_process = multiprocessing.Process(target=service_client, args=(new_socket,))
        # multi_process.start()
        #
        # # 同时存在主进程、子进程指向同一个new_socket对象, 因此需要关闭主进程的new_socket对象
        # new_socket.close()

        # # 多线程
        # multi_thread = threading.Thread(target=service_client, args=(new_socket,))
        # multi_thread.start()

        # # 协程
        gevent.spawn(service_client, new_socket)


    tcp_http_server.close()


if __name__ == '__main__':
    main()