搜索
您的当前位置:首页正文

2018-06-07动态的web服务器

来源:知库网

动态网站:请求的后面是一个程序
WSGI,在被调用函数中的参数设置:

WSGI函数中的参数设置
import一个包名或者模块名,它能把这个包/模块给导进来,并且有一个返回值(和import re 功能一样),返回值是模块的当前名字

研究了一晚上的代码奉上:

# coding:utf-8

import socket
import re
import sys

# 定义一个常量用来接收客户端发起的文件请求地址
# 设置静态文件根目录
HTML_ROOT_DIR = "./html"
WSGI_PYTHON_DIR = "./wsgipython"

from multiprocessing import Process


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

    def start(self):
        self.server_socket.listen(128)
        while True:
            client_socket, client_address = self.server_socket.accept()
            print("[%s, %s]用户连接上了" % client_address)
            handle_client_process = Process(target=self.handle_client, args=(client_socket,))
            handle_client_process.start()
            client_socket.close()

    def start_response(self, status, headers):
        """
                 status = "200 OK"
            headers = [
                ("Content-Type", "text/plain")
            ]
            star
                """
        response_headers = "HTTP1.1 " + status + "\r\n"
        for header in headers:
            response_headers += "%s: %s\r\n" % header
        self.response_headers = response_headers



    def handle_client(self, client_socket):
        # 获取客户端请求
        request_data = client_socket.recv(1024)
        print(request_data)

        # 判断用户发来的请求
        # 使用splitlines来切割不同行
        request_lines = request_data.splitlines()
        for line in request_lines:
            print(line)

        # GET / HTTP/1.1
        request_start_line = request_lines[0]
        file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1)
        method = re.match(r"(\w+) +/[^ ]* ", request_start_line.decode("utf-8")).group(1)

        # time.py
        if file_name.endswith(".py"):
            try:
                m = __import__(file_name[1:-3])
            except Exception:
                self.response_headers = "HTTP/1.1 404 Not Found\r\n"
                response_body = "not found"
            else:
                env = {
                    "PATH_INFO": file_name,
                    "METHOD": method
                }
                response_body = m.application(env, self.start_response)

            response = self.response_headers + "\r\n" + response_body

        else:
            # 通常把常量写在“左边”,变量写在右边,防止少写一个“=”不报错
            if "/" == file_name:
                file_name = "/index.html"

            # 打开文件,读取内容(客户有可能请求图片资源:加上b)
            try:
                file = open(HTML_ROOT_DIR + file_name, "rb")
            except IOError:
                response_start_line = "HTTP/1.1 404 NOT FOUND\r\n"
                response_headers = "Sever: My Sever\r\n"
                response_body = "The file is not found!"
            else:
                file_data = file.read()
                file.close()

                # 构造响应数据
                response_start_line = "HTTP/1.1 200 OK\r\n"
                response_headers = "Sever: My Sever\r\n"
                response_body = file_data.decode("utf-8")

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

        # 向客户端形响应数据
        client_socket.send(bytes(response, "utf-8"))
        # 关闭客户端连接
        client_socket.close()

    def bind(self, port):
        self.server_socket.bind(("", port))


def main():
    sys.path.insert(1, WSGI_PYTHON_DIR)
    http_server = HTTPServer()
    # http_server.set_port()
    http_server.bind(8080)
    http_server.start()


if __name__ == "__main__":
    main()

还有一个附加目录的附加代码:

# coding:utf-8

import time

def application(env, start_response):
    status = "200 OK"
    headers = [
        ("Content-Type", "text/plain")
    ]
    start_response(status, headers)
    return time.ctime()

运行结果:


动态网站的运行结果

森罗万象的代码:
1、sys模块可以配合.insert用来添加模块导入时的搜索路径
2、第一次见到程序中定义了函数,在被导入的包中使用,再传会给程序
3、学习了元组的复加

Top