Python做一个简单的web服务器,外接一个支持wsgi协议框架显示动态数据

import socket
import re
import sys
import mini_frame


# 通过外部传端口号给套接字
# tcp_port = sys.argv[1]


class Mini_Wsgi(object):
    def __init__(self):
        self.tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.tcp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # 绑定端口
        self.tcp_socket.bind(("", 7780))
        # 监听事件
        self.tcp_socket.listen(128)
        # 定义一个字典保存用户的请求
        self.env = dict()


    def index(self, user, new_socket):
        response = "HTTP/1.1 200 ok\r\n" + "content = 'charset=utf-8'"
        response += "\r\n"

        try:
            user_file = "./" + "static" + user
            with open(user_file, "rb") as f:
                html_content = f.read()
            f.close()
            response += html_content.decode("utf-8")
            new_socket.send(response.encode("utf-8"))
        except Exception as ret:
            return "页面不存在"

    def center(self, user, new_socket):
        response = "HTTP/1.1 200 ok\r\n" + "content = 'charset=utf-8'"
        response += "\r\n"
        try:
            user_file = "./" + "static" + user
            with open(user_file, "rb") as f:
                html_content = f.read()
            f.close()
            response += html_content.decode("utf-8")
            new_socket.send(response.encode("utf-8"))
        except Exception as ret:
            return "页面不存在"

    def start_response(self, s_heard, heards):
        self.s_heard = s_heard
        print(heards)
        h = list()
        for a in heards:
            for b in a:
                h.append(b)
                print(h)
            self.heards_all += "%s:%s" % (h[0], h[1])
            self.heards_all += ";"
        print(self.heards_all)


    def server_run(self):

        while True:
            # 等待新用户的链接,返回一个元组
            new_socket, new_addr = self.tcp_socket.accept()
            browser_date = new_socket.recv(1024)
            # 对浏览器返回的数据进行切片处理
            browser_content = browser_date.decode("utf-8").split("\r\n")
            print(browser_content[0], browser_content)
            # browser_content = ['GET /你请求的内容 HTTP/1.1', 'Host: 127.0.0.1:7780', 'Connection: keep-alive', 'Cache-Control: max-age=0', 'Upgrade-Insecure-Requests: 1', 'User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0', 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Encoding: gzip, deflate, sdch, br', 'Accept-Language: zh-CN,zh;q=0.8', '', '']
            # browser_content[0] = GET /你请求的内容 HTTP/1.1
            page_name = re.match(r"[^/]*([/]+.*)[ ].*", browser_content[0])
            # 得到第一条元素,用空格继续切
            # a = browser_content[0].split(" ")
            # 得到用户请求的数据内容
            user = page_name.group(1)
            print(user)
            self.env["PATH_INFO"] = user
            # 判断用户请求的数据以什么结尾,范围什么页面
            # if user.endswith(".html"):
            #     # 调用相对应页面的函数
            #     if user == "/center.html":
            #         self.center(user, new_socket)
            #     else:
            #         self.index(user, new_socket)

            if user.endswith(".html"):

                # 调用框架,返回动态数据
                html = mini_frame.application(self.env, self.start_response)
                print(html)
                print(str(self.heards_all))
                response = "HTTP/1.1 " + self.s_heard + "\r\n" + self.heards_all + "\r\n"
                response += "\r\n"
                response += html
                new_socket.send(response.encode("utf-8"))
                print("------")

            # 如果用户不是.html结尾,则给他加上.html,返回给用户主页
            else:
                response = "HTTP/1.1 200 ok\r\n" + "content = 'charset=utf-8'"
                response += "\r\n"

                # 发送body
                f = open("./static/index.html", "rb")
                html_content = f.read()
                f.close()
                response += html_content.decode("utf-8")
                new_socket.send(response.encode("utf-8"))

            new_socket.close()
            # self.tcp_socket.close()


def main():
    server_web = Mini_Wsgi()
    server_web.server_run()
    server_web.tcp_socket.close()

if __name__ == '__main__':
    main()

下面是mini_frame的代码:

import pymysql

info_path = dict() # 定义一个路由函数用来装饰下面函数 def route(file_name): def set_func(func): info_path[file_name] = func def call_func(*args, **kwargs): return func(*args, **kwargs) return call_func return set_func @route("/center.html") def center(): # user_file = "./" + "static" + user # with open("./static/center.html", "rb") as f: # html_content = f.read() html_content = "" # # 建立数据库的链接 conn = pymysql.connect(host="127.0.0.1", user="root", password="0626",database="python_1", charset="utf8") # 建立游标对象 cursor = conn.cursor() # 执行sql语句 cursor.execute("select * from student;") # 获取查询的数据 vulue = cursor.fetchall() # 关闭游标对象 cursor.close() # 关闭数据库链接 conn.close() people_msg = "序号:%s 名字:%s 出生年月:%s 性别:%s" for date in vulue: html_content += people_msg % (date[0], date[1], date[2], date[3]) html_content += "\t\n" # print(html_content) # html_content += vulue return html_content @route("/index.html") def register(): with open("./static/index.html", "rb") as f: html_content = f.read() return html_content # env = {"center.py":center, # "register.py":register} def application(env, start_response): start_response("200 ok", [("content-type","text/html;charset=utf-8"),]) try: file_name = env["PATH_INFO"] print(file_name) return info_path[file_name]() except Exception as ret: return "404 error"

 

这个程序有个问题就是,我一直开着,浏览器请求过来后,能正常显示出数据,但是等待一会后下面这行代码报错:

# 得到用户请求的数据内容
user = page_name.group(1)

说取不出来值,可如果没有请求过来的话accept默认不是堵塞的吗,为什么还能执行到正则匹配用户请求的值这行代码?(之前用的字符串切割取值,报错,换成正则也是报错,实在是想不明白accept接受到什么请求了打印出来的是个空的,/ 都没有)

现在正恶补下Flask与Django框架。

 

上一篇:Django + Uwsgi + Nginx 的生产环境部署


下一篇:python – 在金字塔项目中使用paste.progress