仿flask-webserver实现

主程序

import socket
import re
import multiprocessing
import mini_web


class WebServer(object):
    """这个服务器类"""
    def __init__(self):
        """初始化tcp服务器"""
        # 1. 创建套接字
        self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        # 2. 绑定
        self.tcp_server_socket.bind(("", 8866))

        # 3. 变为监听套接字
        self.tcp_server_socket.listen(128)

    def service_client(self, new_socket):
        """为这个客户端返回数据"""

        # 1. 接收浏览器发送过来的请求 ,即http请求
        # GET / HTTP/1.1
        # .....
        request = new_socket.recv(1024).decode("utf-8")
        request_lines = request.splitlines()
        print("")
        print(">" * 20)
        print(request_lines)

        # GET /index.html HTTP/1.1
        # get post put del
        file_name = ""
        ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
        if ret:
            file_name = ret.group(1)
            # print("*"*50, file_name)
            if file_name == "/":
                file_name = "/index.html"


        # 如果是html那么会调用mini_web上的application返回页面数据
        if file_name.endswith(".html"):  # 伪静态,动态改装成静态代码,一般就是后缀改成.html

            url_params = dict()  # 给mini_web传参数的
            url_params['file_name'] = file_name

            body = mini_web.application(url_params, self.head_params) #调用框架处理

            head = "HTTP/1.1 %s\r\n" % self.stauts

            # 拼接我们的响应头
            for temp in self.params:
                head += "%s:%s\r\n" % temp

            content = head + "\r\n" + body

            new_socket.send(content.encode("utf-8"))



        else:
            # 返回静态的数据

            # 2. 返回http格式的数据,给浏览器

            try:
                f = open("./static" + file_name, "rb")
            except:
                response = "HTTP/1.1 404 NOT FOUND\r\n"
                response += "\r\n"
                response += "------file not found-----"
                new_socket.send(response.encode("utf-8"))
                print("文件找不到!")

            else:
                html_content = f.read()
                f.close()
                # 2.1 准备发送给浏览器的数据---header
                response = "HTTP/1.1 200 OK\r\n"
                response += "\r\n"
                # 2.2 准备发送给浏览器的数据---boy
                # response += "hahahhah"

                # 将response header发送给浏览器
                new_socket.send(response.encode("utf-8"))
                # 将response body发送给浏览器
                new_socket.send(html_content)

        # 关闭套接
        new_socket.close()

    def run_server(self):
        """用来完成整体的控制"""

        while True:
            # 4. 等待新客户端的链接
            new_socket, client_addr = self.tcp_server_socket.accept()

            # 5. 为这个客户端服务
            p = multiprocessing.Process(target=self.service_client, args=(new_socket,))
            p.start()

            new_socket.close()

        # 关闭监听套接字
        tcp_server_socket.close()

    def head_params(self, stauts, params):
        """ 把响应头存起来进行后期的拼接"""
        self.stauts = stauts
        self.params = params


def main():
    server = WebServer()
    server.run_server()


if __name__ == "__main__":
    main()

webserver 仿照蓝图实现

"""
mini_web.py
"""
#服务器给数据,返回数据给服务器
import re

#定义空字典,用来存储路径跟对应的函数引用
from contextlib import contextmanager
from urllib.request import unquote

from pymysql import connect

url_dict = dict()
#start_response用来框架给服务器传响应头的数据
#environ用来得到服务器传过来的文件路径
def application(environ, start_response):
    """返回具体展示的界面给服务器"""
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')])  #返回响应头

    #根据不同的地址进行判断
    file_name = environ['file_name']

    for key, value in url_dict.items():
        match = re.match(key, file_name) #你的地址跟你的规则一致

        if match:
            #匹配了
            return value(match)  #调用匹配到的函数引用,返回匹配的页面内容

    else:
        # 说明没找到
        return "not page is find!"


#这个装饰器传参,用来完成路由的功能
def route(url_address):  #url_address表示页面的路径
    """主要的目的自动添加路径跟匹配的函数到我们的url字典中"""
    def set_fun(func):
        def call_fun(*args,**kwargs):

            return func(*args,**kwargs)

        #根据不同的函数名称去添加到字典中
        url_dict[url_address] = call_fun

        return call_fun

    return set_fun



#################################################上面是框架部分#############################################
#一个页面一个函数   {"/index.html':index}
# mysql数据库链接
@contextmanager
def mysql_action():
    """对mysql进行操作"""
    # 创建connection 链接
    conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')
    # 获取cursor 对象
    cs1 = conn.cursor()

    # 返回一个游标
    yield cs1

    # 提交
    conn.commit()
    # 关闭
    cs1.close()
    conn.close()



# 主页
@route(r'/(index).html')
def index(match):
    # print(match.group(1))
    with open('./templates/index.html') as f:
        index_content = f.read()

    row_str = """ <tr>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>%s</td>
        <td>
            <input type="button" value="添加" id="toAdd" name="toAdd" systemidvaule="%s">
        </td>
        </tr> """

    with mysql_action() as cs:
        sql = "select id,code,short,chg,turnover,price,highs,time from info"
        cs.execute(sql)
        table_data = cs.fetchall()

    table_str=""
    for i,temp in enumerate(table_data):
        table_str+=row_str%(i+1,temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7],temp[1])

    index_content = re.sub('\{%content%\}',table_str,index_content)

    return index_content

# 添加到个人中心
@route(r'/center.html')
def center(match):
    with open('./templates/center.html') as f:
        center_content = f.read()

    with mysql_action() as cs:
        sql = 'select i.code, i.short,i.chg,i.turnover,i.price,i.highs,f.note_info from focus as f inner join info as i on f.info_id = i.id;'
        cs.execute(sql)
        table_data = cs.fetchall()


    row_str = """ <tr>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>%s</td>
            <td>
                <a type="button" class="btn btn-default btn-xs" href="/update/%s.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
            </td>
            <td>
                <input type="button" value="删除" id="toDel" name="toDel" systemidvaule="%s">
            </td>
        </tr>"""
    table_str = ''
    for temp in table_data:
        table_str += row_str%(temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[0],temp[0])

    center_content = re.sub(r'\{%content%\}',table_str,center_content)
    return center_content

# 添加
@route(r'/add/(\d+).html')
def insert(match):
    code = match.group(1)
    with mysql_action() as cs:
        sql = 'select * from focus where info_id in (select id from info where code=%s);'
        cs.execute(sql,(code,))
        has_flag = cs.fetchone()
        print(has_flag)
        if has_flag:
            return '个人中心已存在此股票'
        else:
            sql1 = 'insert into focus values (select id from info where code = %s)'
            cs.execute(sql1,(code,))
            return '添加成功'

# 更新页面
@route(r'/update/(\d+).html')
def update(match):
    code = match.group(1)
    # 打开文件
    with open('./templates/update.html') as f:
        updata_str = f.read()

    updata_str = re.sub('\{%code%\}',code,updata_str)
    # 查询数据关于note_info
    with mysql_action() as cs:
        sql = 'select f.note_info from focus as f INNER join info as i on f.info_id=i.id WHERE i.code=%s'
        cs.execute(sql,(code,))
        row_data = cs.fetchone()

    note_info = row_data[0]
    if row_data[0] is None:
        note_info = ''
    updata_str = re.sub('\{%note_info%\}',note_info,updata_str)
    return updata_str

# 删除
@route(r'/del/(\d+).html')
def delete(match):
    code = match.group(1)
    with mysql_action() as cs:
        sql = 'delete from focus WHERE info_id= (SELECT id from info WHERE code=%s)'
        cs.execute(sql,(code,))
    return "删除成功"

# 更新备注
@route(r'/update/(\d+)/(.*).html')
def updatenote(match):
    code = match.group(1)
    note_info = match.group(2)
    with mysql_action() as cs:
        sql = 'update focus set note_info = %s where info_id in (select id from info where code = %s);'
        cs.execute(sql,(unquote(note_info),code))
    return '更新成功'
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值