首页 > 其他分享 >web 框架的本质

web 框架的本质

时间:2022-10-08 00:00:26浏览次数:79  
标签:web socket 框架 url 本质 sk ret data conn

web框架的本质——通俗的说,web框架封装了socket、数据库操作、路由分发、模板配置等,留给我们现成的接口,让我们更专注业务逻辑本身。

一个简单的web示例

import socket

# 1. 创建socket对象
sk = socket.socket()

# 2. 绑定IP和端口
sk.bind(('127.0.0.1', 8888))

# 3. 监听
sk.listen(5)

# 4. 循环监听

while 1:
    conn, addr = sk.accept()  # 等待连接
    received_data = conn.recv(8192)  # 接收数据
    print(received_data)  # b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8888\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9,en;q=0.8\r\nCookie: csrftoken=FQW7H4SEVPRqdqIr4vSeiP3EdjX2C0JY7VwCdmXevoXcPjiAMBtNptkiZLHqXo4d\r\n\r\n'

    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')  # 接收数据
    conn.send(b'<h1>Successful</h1>')
    conn.close()  # 关闭连接

现在,使用浏览器地址栏访问http://127.0.0.1:8888/,就会得到Successful

根据不同路径返回不同内容

第一版·普通版

import socket

# 创建socket对象
sk = socket.socket()

# 绑定IP和端口
sk.bind(('127.0.0.1', 8888))

# 监听
sk.listen()

while True:
    # 等待连接
    conn, addr = sk.accept()
    # 接收数据
    data = conn.recv(8192)
    data = data.decode('utf-8')
    url = data.split()[1]
    print(url)
    # 返回状态行
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    if url == '/oumei':
        conn.send(b'<h1>oumei</h1>')
    elif url == '/rihan':
        conn.send(b'<h1>rihan</h1>')
    else:
        conn.send(b'<h1>404</h1>')
    # 关闭连接
    conn.close()

第二版·函数版

import socket
# 创建socket对象
sk = socket.socket()
# 绑定IP和端口
sk.bind(('127.0.0.1', 8888))
# 监听
sk.listen()
def oumei(url):
    ret = 'oumei   -  {}'.format(url)
    return ret.encode('utf-8')
def rihan(url):
    ret = 'rihan////   -  {}'.format(url)
    return ret.encode('utf-8')
while True:
    # 等待连接
    conn, addr = sk.accept()
    # 接收数据
    data = conn.recv(8192)
    data = data.decode('utf-8')
    url = data.split()[1]
    print(url)
    # 返回状态行
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    if url == '/oumei':
        ret = oumei(url)
    elif url == '/rihan':
        ret = rihan(url)
    else:
        ret = b'404 not found'
    conn.send(ret)
    # 关闭连接
    conn.close()

第三版·函数进阶版

import socket
# 创建socket对象
sk = socket.socket()
# 绑定IP和端口
sk.bind(('127.0.0.1', 8888))
# 监听
sk.listen()
def oumei(url):
    ret = 'oumei   -  {}'.format(url)
    return ret.encode('utf-8')
def rihan(url):
    ret = 'rihan////   -  {}'.format(url)
    return ret.encode('utf-8')
def guochan(url):
    ret = 'guochan   -  {}'.format(url)
    return ret.encode('utf-8')
list = [
    ('/oumei', oumei),
    ('/rihan', rihan),
    ('/guochan', guochan),
]
while True:
    # 等待连接
    conn, addr = sk.accept()
    # 接收数据
    data = conn.recv(8192)
    data = data.decode('utf-8')
    url = data.split()[1]
    print(url)
    # 返回状态行
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    func = None
    for i in list:
        if i[0] == url:
            func = i[1]
            break
    if func:
        ret = func(url)
    else:
        ret = b'404 not found'
    conn.send(ret)
    # 关闭连接
    conn.close()

第四版·反射版

ps:仅针对当前脚本使用的反射。

import socket
sk = socket.socket()
sk.bind(("127.0.0.1", 8888))
sk.listen()
class Server(object):
    """ 模拟多个页面 """
    def europe(self):
        return "<h1>europe</h1>".encode('utf8')
    def kkc(self):
        return "<h1>kkc</h1>".encode('utf8')
    def notfond(self):
        return "<h1>404 not fond</h1>".encode('utf8')
while 1:
    # 等待请求
    conn, address = sk.accept()
    # 获取数据
    data = conn.recv(8192).decode('utf8')
    # 处理请求拿到请求路径
    # print(data)
    url = data.split(' ', 2)[1][1:]
    # print(url, data)
    # 返回数据
    server_obj = Server()
    if hasattr(server_obj, url):
        res = getattr(server_obj, url)()
    else:
        res = server_obj.notfond()
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    conn.send(res)
    conn.close()

返回HTML页面

首先在同级目录有个index.html页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>

<h1>index page</h1>

</body>
</html>

然后写server端:

import socket

# 创建socket对象
sk = socket.socket()

# 绑定IP和端口
sk.bind(('127.0.0.1', 8888))

# 监听
sk.listen()


def oumei(url):
    ret = 'oumei   -  {}'.format(url)
    return ret.encode('utf-8')


def rihan(url):
    ret = 'rihan////   -  {}'.format(url)
    return ret.encode('utf-8')


def guochan(url):
    ret = 'guochan   -  {}'.format(url)
    return ret.encode('utf-8')


def index(url):
    with open('index.html', 'rb') as f:
        ret = f.read()
        return ret


list = [
    ('/oumei', oumei),
    ('/rihan', rihan),
    ('/guochan', guochan),
    ('/index', index),
]

while True:
    # 等待连接
    conn, addr = sk.accept()
    # 接收数据
    data = conn.recv(8192)
    data = data.decode('utf-8')
    url = data.split()[1]
    print(url)

    # 返回状态行
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    func = None
    for i in list:
        if i[0] == url:
            func = i[1]
            break

    if func:
        ret = func(url)
    else:
        ret = b'404 not found'

    conn.send(ret)

    # 关闭连接
    conn.close()

返回动态页面

在同级目录有个tiem.html页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>当前时间是: @@time@@ </h1>
</body>
</html>

在来实现代码:

import socket
import time

# 创建socket对象
sk = socket.socket()

# 绑定IP和端口
sk.bind(('0.0.0.0', 8000))

# 监听
sk.listen()


def oumei(url):
    ret = 'oumei   -  {}'.format(url)
    return ret.encode('utf-8')


def rihan(url):
    ret = 'rihan////   -  {}'.format(url)
    return ret.encode('utf-8')


def guochan(url):
    ret = 'guochan   -  {}'.format(url)
    return ret.encode('utf-8')


def index(url):
    with open('index.html', 'rb') as f:
        ret = f.read()
        return ret


def timer(url):
    now = time.strftime('%Y-%m-%d %H:%M:%S')
    with open('time.html', 'r', encoding='utf-8') as f:
        data = f.read()
        data = data.replace('@@time@@', now)

        return data.encode('utf-8')


list = [
    ('/oumei', oumei),
    ('/rihan', rihan),
    ('/guochan', guochan),
    ('/index', index),
    ('/time', timer),
]

while True:
    # 等待连接
    conn, addr = sk.accept()
    # 接收数据
    data = conn.recv(8096)
    data = data.decode('utf-8')
    url = data.split()[1]
    print(url)

    # 返回状态行
    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
    func = None
    for i in list:
        if i[0] == url:
            func = i[1]
            break

    if func:
        ret = func(url)
    else:
        ret = b'404 not found'

    conn.send(ret)

    # 关闭连接
    conn.close()

总结

正如文章开始所示,web框架本质就是一个socket服务端。

web框架功能:

  • socket收发消息
  • 根据不同的路径返回不同的内容
  • 可以返回动态页面(使用字符串替换等方式进行模板渲染)

标签:web,socket,框架,url,本质,sk,ret,data,conn
From: https://www.cnblogs.com/windyrainy/p/16767546.html

相关文章

  • Webhook到底是个啥?
    服务器:​​JenkinsServer​​​​​GitServer​​​​​AppServer​​​关键词:​​​nodejs​​​​​ngrok​​​​​githubwebhook​​在配置Jenkins实现前端自......
  • 实用webpack插件之DefinePlugin
    通过阅读这篇文章,可以学习到如何使用DefinePlugin插件使得前端项目更加工程化,说清晰点就是如何使用这个插件,在编译阶段根据NODE_ENV自动切换配置文件,提升前端开发效率。Defi......
  • WebRTC运行机制
           ......
  • web RTC目录结构
        ......
  • webvm 基于webassembly 的虚拟机
    webvm是leaningtech团队开源的基于web的虚拟机工具,使用了webassembly能力,基于没有修改的debian系统开发的核心技术基于了leaningtech的CheerpX虚拟引擎,有比较有意思......
  • Totoro 框架在自动化测试领域的深耕与收获
    自动化测试框架Totoro是由蚂蚁金服终端工程技术部实验平台技术组自主研发的一套自动化测试框架,支持Android、iOS、HTML5、小程序、Weex、Cube等移动端自动化测试场景。......
  • 基于Scrapy框架的二手房数据获取及分析
    ​诸如房价这些问题近些年来一直是国内的热点话题。其中房价变化大,房价高等一系列问题也引起大量的关注。因此,本系统致力于利用现有的技术对某二手房交易网站进行数据的爬......
  • MyBatis框架:第八章:自定义结果集,一对一,一对多,延迟加载,赖加载
    13.1、自定义结果集介绍自定义结果集,可以给复杂的对象使用。也就是对象内又嵌套一个对象。或者一个集合。在这种情况下。前面学过的知识点,已经无法直接获取出对象内对象......
  • 字节开源go框架
    httphertz:​​https://github.com/cloudwego/hertz​​​thriftkitex:​​https://github.com/cloudwego/kitex​​​gopkg:​​https://github.com/bytedance/gopkg​​......
  • 三分支网络——目前目标检测性能最佳网络框架
    尺度变化是目标检测中的关键挑战之一。今天要说的这个技术就特别厉害,在目标检测领域中,目前是性能最强的一个框架。下面让我们一起去见证下它的优势所在。本次介绍的算法框架......