欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一个简单的动态web服务器

程序员文章站 2022-05-08 22:53:58
...

这个动态web服务器的思路是在静态服务器的基础上添加对URL的判断,如果URL中带有脚本信息,那么服务器会去执行脚本而不是直接返回静态界面

 

#-*-coding:utf-8-*-
import sys
import re
from socket import *
from multiprocessing import Process

#设置静态文件根目录
HTTP_ROOT_DIR = "./html"

WSGI_PYTHON_DIR = "./wsgipython"

class HTTPServer(object):
    ''''''
    def __init__(self):
        self.tcp_socket = socket(AF_INET, SOCK_STREAM)
        self.tcp_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)


    def start(self):
        self.tcp_socket.listen(128)
        while True:
            try:
                cli_socket, addrs = self.tcp_socket.accept()
                print("%s  %s:用户已连接" % (addrs[0], addrs[1]))
                p = Process(target=self.handle_client, args=(cli_socket,))
                p.start()
                cli_socket.close()
            except:
                print("服务器已经关闭")
                cli_socket.close()

        tcp_socket.close()

    def start_response(self, status, headers):
        self.response_start = "HTTP/1.1 " + status + "\r\n"
        server_headers = ""
        for header in headers:
            server_headers += "%s: %s\r\n"%header
        self.response_headers = server_headers

    def handle_client(self,cli_socket):
        # 接收数据
        request_data = cli_socket.recv(1024)
        # 解析HTTP报文协议 request_data
        print("requst_data:", request_data)

        # 处理响应数据
        request_lines = request_data.splitlines()
        print(request_lines)
        request_da = request_lines[0]
        # 获取用户想要的请求名
        file_name = re.match(r"\w+ +(/[^ ]*) ", request_da.decode("utf-8")).group(1)

        if file_name.endswith(".py"):
            # 处理py文件
            m = __import__(file_name[1:-3])
            env = {}
            response_body = m.application(env, self.start_response)
            response_start_line = self.response_start
            response_header = self.response_headers

        else:
            # 判定一下特殊情况,字符串写在左侧可以避免把“==”写成“=”时当成赋值语句
            if "/" == file_name:
                file_name = "/index.html"
            # 打开请求文件
            try:
                f = open(HTTP_ROOT_DIR + file_name, "rb")
                file_data = f.read()
                f.close()
            except IOError:
                response_start_line = "HTTP/1.1 404 Not Found\r\n"
                response_header = "Server: My server\r\n"
                response_body = "Not Found"
            else:
                # 构造响应数据
                response_start_line = "HTTP/1.1 200 OK\r\n"
                response_header = "Server: My server\r\n"
                response_body = file_data.decode("utf-8")

        response = response_start_line + response_header + "\r\n" + response_body
        print("response data:", response)

        # 发送数据
        cli_socket.send(bytes(response, "utf-8"))
        # cli_socket.send(response)

        # 关闭套接字
        cli_socket.close()
        print("链接已经断开")

    def bind(self, port):
        self.tcp_socket.bind(port)


def main():
    sys.path.insert(1,WSGI_PYTHON_DIR)
    http_server = HTTPServer()
    http_server.bind(("",8000))
    http_server.start()

if __name__ == '__main__':
    main()