一篇博客搞定Django基础

web框架本质

一. scoket 回顾

1.TCP/UDP协议

TCP:一种面向连接的、可靠的、传输层通信协议(比如:打电话);优点:可靠,稳定,传输完整稳定,不限制数据大小;缺点:慢,效率低,占用系统资源高,一发一收都需要对方确认
应用:Web浏览器,电子邮件,文件传输,大量数据传输的场景

服务端:七步: 创建对象–>绑定ip和端口号–>开启监听–>三次握手–>处理收发逻辑–>四次挥手–>退还端口

import socket
#1.创建对象
sk = socket.socket()
#2.绑定ip和端口
sk.bind(("127.0.0.1",9001))
#3.开启监听
sk.listen()
#4.三次握手
conn,addr = sk.accept()
#5.处理收发数据逻辑
res = conn.recv(1024)
print(res.decode('utf-8'))
#6.四次挥手
conn.close()
#7.退还端口
sk.close()

客户端:四步:创建对象–>建立连接–>处理收发消息逻辑–>关闭连接

import socket
#1.创建对象
sk = socket.socket()
#2.建立连接
sk.connect(('127.0.0.1',9001))
#3.处理收发消息逻辑
sk.send('你好'.encode())
#4.关闭连接
sk.close()

UDP:一种无连接的,不可靠的传输层通信协议(比如:发短信); 优点:速度快,可以多人同时聊天,耗费资源少,不需要建立连接; 缺点:不稳定,不能保证每次数据都能接收到
应用:IP电话,实时视频会议,聊天软件,少量数据传输的场景

服务端:四步:创建对象–>绑定ip和端口–>收发消息(一开始只能收)–>关闭连接

import socket
#1.创建对象
sk = socket.socket(type=socket.SOCK_DGRAM)
#2.绑定ip和端口
sk.bind(('127.0.0.1',9002))
#3.收发消息
msg,cli_addr = sk.recvfrom(1024)
print(msg.decode())
sk.sendto('你好'.encode(),cli_addr)
#4.关闭连接
sk.close()

客户端:三步:创建对象–>发收消息–>关闭连接

import socket
#1.创建对象
sk = socket.socket(type=socket.SOCK_DGRAM)
#2.收发消息
sk.sendto('hello'.encode(),('127.0.0.1',9002))
msg,server_addr = sk.recvfrom(1024)
print(msg.decode())
#3.关闭连接
sk.close()

二.HTTP协议

HTTP是一个客户端终端(用户)和服务器端(网站)请求和应答的标准 .

1.http工作原理

  1. 客户端连接到Web服务器
  2. 发送HTTP请求
  3. 服务器接受请求并返回HTTP响应
  4. 释放连接TCP连接
  5. 客户端浏览器解析HTML内容

2.请求方法和响应方法

请求:

在这里插入图片描述
​ 请求方法:GET方法:读取数据 POST方法…

响应:

在这里插入图片描述
​ 状态码:1xx~4xx:

​ 1xx消息——请求已被服务器接收,继续处理

​ 2xx成功——请求已成功被服务器接收、理解、并接受

​ 3xx重定向——需要后续操作才能完成这一请求

​ 4xx请求错误——请求含有词法错误或者无法被执行

​ 5xx服务器错误——服务器在处理某个正确请求时发生错误

三.自定义的web框架

自定义的web框架基于HTTP1.1和TCP主要是处理收发逻辑和如何连接到数据库.

1.多函数的自定义web框架

分析: 输入127.0.0.1:9000 —> 浏览器发送get请求 —> get 路径 HTTP1.1\r\n… —> 服务端答应 —> HTTP/1.1 200 ok\r\n\r\n 响应正文

import socket,time
#######socket---tcp连接#########################################
sk = socket.socket()
sk.bind(('127.0.0.1',9000))
sk.listen()
#######回消息的函数###############################################
def html(coon):     #动态页面
    cur_time = time.strftime("%Y-%m-%d %H:%M:%S") #是字符串类型,如果是=时间戳是浮点型
    with open('home.html',mode='r',encoding='utf-8') as f:
        data = f.read()
    data = data.replace("xxoo",cur_time).encode('utf-8')
    conn.send(data)
    conn.close()

def ico(conn):
    with open('logo.ico','rb') as f :
        data = f.read()
    conn.send(data)
    conn.close()

def css(conn):
    with open('test.css','rb') as f :
        data = f.read()
    conn.send(data)
    conn.close()

def jpg(conn):
    with open('bg.jpg','rb') as f :
        data = f.read()
    conn.send(data)
    conn.close()

def login(conn):
    with open('login.html','rb') as f :
        data = f.read()
    conn.send(data)
    conn.close()

def js(conn):
    with open('test.js','rb') as f :
        data = f.read()
    conn.send(data)
    conn.close()

def zhuce(conn):
    with open('zhuce.html','rb') as f :
        data = f.read()
    conn.send(data)
    conn.close()

urlpatterns = [
    ('/',html),
    ('/logo.ico',ico),
    ('/test.css',css),
    ('/bg.jpg',jpg),
    ('/login.html',login),
    ('/test.js',js),
    ('/zhuce.html',zhuce)
]

while True:
    conn,addr = sk.accept()
    from_browser_msg = conn.recv(1024)
    print(from_browser_msg)
    #从请求中获取路径
    path = from_browser_msg.decode().split(' ')[1]
    #发送响应的状态行
    conn.send(b'HTTP/1.1 200 ok\r\n\r\n')
    #发送响应正文
    for i in urlpatterns:
        if path == i[0]:
            i[1](conn)

sk.close()

home.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="icon" href="logo.ico">
    <link rel="stylesheet" href="test.css">
</head>
<body class="c1">
    <h1 style="color: red ">欢迎来到祖安</h1>
    <h2 style="color: red ">你访问的时间是xxoo</h2>
    <button id="d1">登录</button>
    <a href="http://127.0.0.1:9000/zhuce.html" style="color: yellow">注册</a>
</body>
<script src="test.js"></script>
</html>

test.css文件:

.c1{
   
    background: url('bg.jpg') no-repeat ;
    background-size:100%,100%;
}

test.js文件:

var d = document.getElementById('d1')
d.onclick = function () {
   
    window.location.href="http://127.0.0.1:9000/login.html"
}

login.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="http://127.0.0.1:9000/login" method="post">
    用户名<input type="text">
    密码 <input type="password">
    <input type="submit">
</form>
</body>
</html>

zhuce.html文件:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1 style="color: red">不会吧不会吧,不会真有人想当祖安人吧</h1>
</body>
</html>

2.wsgiref模块定义的web框架

**分析:**wsgiref模块封装了socket模块,用法如下:

from wsgiref.simple_server import make_server
def application(environ, start_response):
     '''
    environ: 是全部加工好的请求信息,加工成了一个字典,通过字典取值的方式就能拿到很多你想要拿到的信息
    start_response: 帮你封装响应信息的(响应行和响应头)
    :return: 需要发送的数据
    '''
    path = environ['PATH_INFO']  #获取路径
    method = environ['REQUEST_METHOD'] #获取请求方法
    content_length = int(environ.get('CONTENT_LENGTH',0)) #获取请求数据的长度
    request_data = environ['wsgi.input'].read(content_length) #post请求读取请求数据的方式 结果为字节流.decode()
    '''
    写逻辑
    data = ...
    '''
    start_response('200 OK', [('a','1'),])
    return [data]
httpd = make_server('127.0.0.1', 8001, application) #类似socketserver
httpd.serve_forever() #监听请求

**补充:**from urllib.parse import parse_qs , parse_qs方法用来解析数据,用法如下:

from urllib.parse import parse_qs
print('请求数据为', data) #请求数据为 username=asdf&password=asdf
data = parse_qs(data)
print('格式化之后的数据',data) #格式化之后的数据 {'username': ['asdf'], 'password': ['asdf']}
uname = data.get('username') #通过字典可以直接取出
pwd = data.get('password')

基于上述两个模块可以改造上面的web框架并连接到数据库,一个完整的web框架就完成了

主程序:

import time
from urllib.parse import parse_qs                   #parse : url的解析,合并,编码,解码
from wsgiref.simple_server import make_server       #按规范封装了socket
from auth import check

def html(environ):
    cur_time = time.strftime("%Y-%m-%d %H:%M:%S")          #是字符串类型,如果是=时间戳是浮点型
    with open('home.html',mode='r',encoding='utf-8') as f:
        data = f.read()
    data = data.replace("xxoo",cur_time).encode('utf-8')
    return data

def ico(environ):
    with open('logo.ico','rb') as f :
        data = f.read()
    return data

def css(environ):
    with open('test.css','rb') as f :
        data = f.read()
    return data

def jpg(environ):
    with open('bg.jpg','rb') as f :
        data = f.read()
    return data

def login(environ):
    if environ['REQUEST_METHOD'] == 'GET':
        with open('login.html','rb') as f :
            data = f.read()
        return data
    else:
        content_length = int(environ.get('CONTENT_LENGTH', 0))
        data = environ['wsgi.input'].read(content_length).decode('utf-8')
        data = parse_qs(data)
        uname = data.get('username')
        pwd = data.get('password')
        staut = check(uname,pwd)
        if staut:
            with open('login_suc.html','rb') as f :
                data = f.read()
                return data
        else:
            return '登录失败'.encode('gbk')

def js(environ):
    with open('test.js','rb') as f :
        data = f.read()
    return data

def zhuce(environ):
    with open('zhuce.html','rb') as f :
        data = f.read()
    return data

urlpatterns = [
    ('/',html),
    ('/logo.ico',ico),
    ('/test.css',css),
    ('/bg.jpg',jpg),
    ('/login.html',login),
    ('/test.js',js),
    ('/zhuce.html',zhuce),
    ('/login',login)
]

def application(environ,start_response):
    path = environ['PATH_INFO']
    start_response('200 OK',[('a','1'),])
    for i in urlpatterns:
        if i[0] == path:
            data = i[1](environ)
            break
    else:
        data = b'404 not found'
    return [data]
httpd = make_server('192.168.13.26',9000,application)
httpd.serve_forever()

auth.py 连接数据库程序:

import pymysql
def check(uname,pwd):
    conn = pymysql.connect(host='127.0.0.1',user='root',password='',database='db0913',port=3306)
    cursor = conn.cursor()
    sql = 'select * from t1 where id = %s and name = %s'
    res = cursor.execute(sql,(uname,pwd))
    return res

login_suc.html 登录成功界面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值