python之web应用、基于wsgiref自定义web框架及其它socket服务端

1、web应用

1.1、定义

Web应用程序是基于B/S架构的,其中B指的是浏览器,负责向S端发送请求信息,而S端会根据接收到的请求信息返回相应的数据给浏览器,强调:S端由server和application两大部分构成,如图所示:
在这里插入图片描述

1.2、web应用的优点
  • 不需要客户端
  • 更新直接在服务端更新,客户端感知不到
  • 跨平台性好
1.3、web应用的缺点
  • 强调浏览器的适用性
  • 用户的数据都保存在软件厂商那边
1.4、bs、cs架构

bs:浏览器—服务端(本质还是cs)
cs:客户端—服务端

1.5、基于socket写一个web应用
1.5.1、main.py
import socket

def server_run():
    soc = socket.socket()
    soc.bind(('127.0.0.1', 8008))
    soc.listen(5)
    while True:
        conn, addr = soc.accept()
        recv_data = conn.recv(1024)
        print(recv_data)
        # 1 直接在send里写,发送给客户端
        # conn.send(b'HTTP/1.1 200 OK\r\n\r\n<h1>hello web</h1><img src="https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike92%2C5%2C5%2C92%2C30/sign=5e3814acf9edab64607f4592965fc4a6/14ce36d3d539b600c0c465d0eb50352ac65cb74b.jpg"></img>')
        #2 打开一个html文件,发送给客户端
        # with open('index.html','r',encoding='utf-8') as f:
        #     data=f.read()
        # conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8'))
        # 3 动态网页,字符串替换
        import time
        now=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        print(now)
        with open('index.html','r',encoding='utf-8') as f:
            data=f.read()
        data=data.replace('@@@',now)
        conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8'))
        conn.close()

if __name__ == '__main__':
    server_run()
1.5.2、index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>@@@</h2>

<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1601099256336&di=f664b8fa21a9d3e642112a1e1cc8d885&imgtype=0&src=http%3A%2F%2Fa3.att.hudong.com%2F14%2F75%2F01300000164186121366756803686.jpg" alt="">
</body>
</html>

2、web框架

Web框架(Web framework)是一种开发框架,用来支持动态网站、网络应用和网络服务的开发。这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方法。web框架已经实现了很多功能,开发人员使用框架提供的方法并且完成自己的业务逻辑,就能快速开发web应用了。浏览器和服务器的是基于HTTP协议进行通信的,web框架就是在以上几十行代码基础上扩展出来的,有很多简单方便使用的方法,大大提高了开发的效率

2.1、基于wsgiref写一个web框架

1、socket自己写,借助于一个模块,已经实现了socket
2、wsgiref:django默认使用的
3、在web框架上继续开发

  • 以后路径都去urls.py中写
  • 路径匹配以后执行的函数,都放在views.py
  • 数据库相关操作,在models.py中

wsgiref简单使用

from wsgiref.simple_server import make_server

def server(environ, start_response):  # 必须传两个参数
    # environ是字典,http请求拆成字典,请求方式,请求地址,请求头...
    # start_response: 响应对象,响应状态码,响应头放到里面
    start_response('200 OK', [('Content-Type', 'text/html')])
    if environ.get('PATH_INFO') == '/index':  # 请求地址
        data = '我是index页面'.encode('utf-8')

    elif environ.get('PATH_INFO') == '/login':
        data = '我是login页面'.encode('utf-8')
    else:
        data = b'<h1>Hello, web!</h1>'
    return [data]

if __name__ == '__main__':
    # app是可调用对象,可以加括号执行的(函数内存地址)
    myserver = make_server('127.0.0.1', 8081, server)  # 只要客户端发送一次请求,就会调用server()
    myserver.serve_forever()  # 服务就起来了,相当于之前写的socket一直监听8081端口
2.2、基于wsgiref自定义web框架

在这里插入图片描述

2.2.1、models.py
'''
链接数据库返回字典格式:
cursor=pymysql.cursors.DictCursor
'''
import pymysql
# 连接数据库
conn = pymysql.connect(host='127.0.0.1',port= 3307,user = 'root',passwd='root',db='web') # db: 库名
# 创建游标
cur = conn.cursor()

sql='''
create table userinfo(
        id INT PRIMARY KEY ,
        name VARCHAR(32) ,
        password VARCHAR(32)
)
'''
cur.execute(sql)
# 提交
conn.commit()
# 关闭指针对象
cur.close()
# 关闭连接对象
conn.close()
2.2.2、myserver.py
from wsgiref.simple_server import make_server
from urls import url_patters

def mya(environ, start_response):
    # print(environ)
    start_response('200 OK', [('Content-Type', 'text/html')])
    func = None
    for item in url_patters:
        if item[0] == environ.get('PATH_INFO'):
            func = item[1]
            break
    if func:
        data = func(environ)
        return [data]
    else:
        return [b'404']

if __name__ == '__main__':
    myserver = make_server('', 8011, mya)
    print('监听8010')
    myserver.serve_forever()
2.2.3、urls.py
from views import *
url_patters = [
    ('/login', login),
    ('/index', index),
    ('/time', time),
]
2.2.4、views.py
def index(environ):
    with open('templates/index.html', 'rb') as f:
        data = f.read()
    return data
def time(environ):
    import datetime
    now=datetime.datetime.now().strftime('%y-%m-%d %X')
    print(now)
    return now.encode('utf-8')
from urllib.parse import parse_qs
import pymysql
def login(request):
    if request.get("REQUEST_METHOD") == "POST":
        try:
            request_body_size = int(request.get('CONTENT_LENGTH', 0))
        except (ValueError):
            request_body_size = 0

        request_body = request['wsgi.input'].read(request_body_size)
        data = parse_qs(request_body)

        user = data.get(b"user")[0].decode("utf8")
        pwd = data.get(b"pwd")[0].decode("utf8")

        # 连接数据库
        conn = pymysql.connect(host='127.0.0.1', port=3307, user='root', passwd='root', db='web')  # db: 库名
        # 创建游标
        cur = conn.cursor()
        SQL = "select * from userinfo WHERE NAME ='%s' AND PASSWORD ='%s'" % (user, pwd)
        cur.execute(SQL)

        if cur.fetchone():
            f = open("templates/backend.html", "rb")
            data = f.read()
            data = data.decode("utf8")
            return data.encode("utf8")
        else:
            print("OK456")
            return b"user or pwd is wrong"
    else:
        f = open("templates/login.html", "rb")
        data = f.read()
        f.close()
        return data
2.2.5、tempaltes下backend.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
登录成功
</body>
</html>
2.2.6、tempaltes下index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
index
</body>
</html>
2.2.7、tempaltes下login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<h4>登录页面</h4>
<form action="http://127.0.0.1:8011/login" method="post">
     用户名 <input type="text" name="user">
     密码 <input type="text" name="pwd">
    <input type="submit">
</form>
</body>
</html>

3、其它socket服务端

'cgi': CGIServer,
'flup': FlupFCGIServer,
'wsgiref': WSGIRefServer,
'waitress': WaitressServer,
'cherrypy': CherryPyServer,
'paste': PasteServer,
'fapws3': FapwsServer,
'tornado': TornadoServer,
'gae': AppEngineServer,
'twisted': TwistedServer,
'diesel': DieselServer,
'meinheld': MeinheldServer,
'gunicorn': GunicornServer,
'eventlet': EventletServer,
'gevent': GeventServer,
'geventSocketIO':GeventSocketIOServer,
'rocket': RocketServer,
'bjoern' : BjoernServer,
'auto': AutoServer,

都遵循一个协议wsgi(Web Server Gateway Interface web服务网关接口)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值