HTTP基本原理
1.http简述:
http协议永远都是客户端发起请求,服务端回送请求。客户端和服务端本质上是一个socket客户端和服务端,http协议可以说是基于socket的再上层封装
2.http特性:
1)短链接
2)被动响应
3)无状态
Socket基本原理
结合上图及下面的python代码,我们来一起学习一下socket的基本原理
1 #!/usr/bin/env python 2 #_*_coding:utf-8_*_ 3 #Author:Tiger At 4 5 import socket #导入socket模块 6 7 8 def main(): 9 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建socket实例,AF_INET表示IPV4,SOCK_STREAM表示TCP连接 10 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) #表示客户端失去连接后,服务端可以立即释放端口 11 sock.bind(('0.0.0.0', 8000)) #进行服务器的端口绑定 12 #开始TCP监听。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。 13 sock.listen(5) 14 15 while True: 16 # 等待浏览器访问 17 conn, addr = sock.accept() 18 # 接收浏览器发送来的请求内容 19 data = conn.recv(1024) 20 print(data) 21 22 # 给浏览器返回内容 23 conn.send(b"HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n") 24 conn.send("电脑前的你长的真好看!".encode("utf-8")) 25 26 # 关闭和浏览器创建的socket连接 27 conn.close() 28 29 30 if __name__ == "__main__": 31 main()
总结一下就是:创建socket实例->绑定IP地址及端口号(对外提供服务)->监听外来请求->接受请求->处理请求(数据交互)->关闭连接
#!/usr/bin/env python #_*_coding:utf-8_*_ #Author:Tiger At import socket client = socket.socket() #创建socket实例 client.connect(("x.x.x.x",9999)) #与服务器建立连接 while True: msg = input(">>>>>:").strip() if len(msg) == 0:continue client.send(msg.encode('utf-8')) #发送请求 data = client.recv(1024) #接收数据 print(data) client.close() #关闭连接
总结一下就是:创建socket实例->主动发起连接->发送请求->接收结果->关闭连接
讲了这么多,这个到底与http有什么关系呢?上面我们提到过说:http的本质其实就是socket客户端和服务端,只是client变成了浏览器,而服务端只需要能处理浏览器的请求,并返回
相应结果就可以了。我这边摘出了"socket_server"中的部分代码,做详细解释:
# 给浏览器返回内容
conn.send(b"HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n") #表示:返回状态码为 200 Content-Type表示文本格式 charset表示字符编码。这些都是浏览器所需的信息不能缺少
conn.send("电脑前的你长的真好看!".encode("utf-8"))
#注上面要是直接写成 conn.send("电脑前的你长的真好看!"),只有再shell界面中能看到这个字符串了,浏览器是不会识别的
WSGI简介
WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app(应用程序)与web server(socket服务端)之间接口格式,实现web app与web server间的解耦。
通俗的说:当规范建立后,程序就不再重复编写web server(socket服务端),而是直接使用现成的实现WSGI的模块(例如:wsgiref、uwsgi、werkzeug),从而让程序员更加专注与业务代码
与其重复造轮子,不如直接用现成的。
Python的wsgiref是基于WSGI规范封装的模块,我们可以在这个模块基础上开发我们的web server
#!/usr/bin/env python #_*_coding:utf-8_*_ #Author:Tiger At from wsgiref.simple_server import make_server #导入wsgiref模块 def run_server(environ, start_response): """ 当有用户在浏览器上访问:http://127.0.0.1:8000/, 立即执行该函数并将函数的返回值返回给用户浏览器 :param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等 :param start_response: 响应相关 :return: """ start_response('200 OK',[('Content-Type', 'text/html;charset=utf-8')]) return [bytes('<h1>我旁边的这个人长的真丑呀!!',encoding='utf-8'),] if __name__ == '__main__': httpd = make_server('0.0.0.0',8001,run_server) httpd.serve_forever()
可以清晰的看到,使用了wsgiref模块后,我们直接使用make_server代替了服务器初始化的过程,使代码更加规范。我们再来看看下面的代码:
#!/usr/bin/env python #_*_coding:utf-8_*_ #Author:Tiger At from wsgiref.simple_server import make_server def western(): return "欢迎来到欧美专区" def japan(): return "欢迎来到日本人专区" def routers(): """负责把url与对应的方法关联起来""" urlpatterns = ( ('/western/',western), ('/japan/',japan), ) return urlpatterns def run_server(environ, start_response): """ 当有用户在浏览器上访问:http://127.0.0.1:8000/, 立即执行该函数并将函数的返回值返回给用户浏览器 :param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等 :param start_response: 响应相关 :return: """ start_response('200 OK',[('Content-Type', 'text/html;charset=utf-8')]) url = environ.get("PATH_INFO") urlpatterns = routers() func = None for item in urlpatterns: if item[0] == url: func = item[1] break if func: return [bytes(func(),encoding="utf-8"),] else: return [bytes('404 not found.',encoding="utf-8"),] if __name__ == '__main__': httpd = make_server('0.0.0.0',8001,run_server) httpd.serve_forever()
对比之前的代码,我们可以看到我们做了相关路由选择功能urlpatterns,因此我们可以根据访问的url不通而显示不同的内容
小结
Web框架的本质
虽然自己写Web Server比较麻烦,但是我们从中也了解web框架的本质:
a.浏览器是socket客户端,网站是socket服务端
b.wsgi,是一个规范,wsgiref实现了这个规范并在其内部实现了socket服务端
c.根据 url 的不同执行不同函数,即:路由系统
d.函数,即:视图函数
e.图片、css、js文件 统一称为静态文件,需要读取内容直接返回给用户浏览器
Django初识
写在前面,既然web框架的本质如上面的小结所示,那django基本也是按照这个思路进行相应功能的封装和优化的,从而使用户更加关注于业务代码,让我们开始Django吧
开始一个Django项目:
1.使用 django-admin startproject mysite(此为项目名称,可根据具体需求定义)
├───mysite
│ │ manage.py #管理程序的文件,启动和结束等
│ │
│ └───mysite
│ settings.py #程序的配置文件
│ urls.py #程序的路由系统,即url和处理其函数的对应关系
│ wsgi.py #指定框架的wsgi
│ __init__.py
2.创建APP
python manage.py startapp app01(此为业务模块名称)
├───app01
│ │ admin.py #业务admin管理(数据库后台)
│ │ apps.py #业务配置(django把项目和app关联起来的一个文件)
│ │ models.py #数据库相关操作
│ │ tests.py #业务单元测试
│ │ views.py #业务代码(重要)
│ │ __init__.py
│ │
│ └───migrations #数据库相关
│ __init__.py
3.第一次django 请求
1)匹配路由,路由分发器查找用户请求得url对应关系
a.如果找到了业务函数就调用
b.找不到就报404
2)业务函数,执行业务逻辑
3)返回数据给浏览器
具体实现方式:
1) urls.py 编写路由
2)在views.py写一个业务函数
a.编写业务代码
b.通过HttpResponse方法返回数据给前端
3)python manage.py runserver 0.0.0.0:8000
注:127.0.0.1 环回测试地址,代表本机IP地址,访问127.0.0.1:80表示本机的80号端口,且仅表示内网访问
0.0.0.0 网络地址,0.0.0.0:80也表示本机IP地址,以外网的方式访问
这两种表示法用以对计算机端口进行权限设置
如果listen(0.0.0.0:XX),则这个可以被外部网络访问
而 listen(127.0.0.1:XX) 则这个端口只能被本机访问
4.模板初探
1)配置settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,"html")],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
2)views.py 调用render方法
return render(response,"login.html")
声明:
1.本节内容用户自我学习与自我回顾使用
2.本文主要参考:https://www.cnblogs.com/alex3714/articles/8662706.html
https://www.cnblogs.com/alex3714/articles/5830365.html
进行梳理学习,详细内容可参阅如上URL。
3.希望可以与大家一起共同进步。