前端简介/IO模型/协程
协程
进程:资源单位
线程:工作单位
协程:是程序员单方面意淫出来的名词>>>:单线程下实现并发
CPU被剥夺的条件
1、程序长时间占用
2、程序进入IO操作
并发
切换+保存状态
以往学习的是:多个任务(进程、线程)来回切换
欺骗CPU的行为
单线程下我们如果能够自己检测IO操作并且自己实现代码层面的切换
那么对于CPU而言我们这个程序就没有IO操作,CPU会尽可能的被占用
代码层面
第三房gevent模块,能够自主检测IO行为并切换
mac本安装gevent:
打开终端-->pythn3.6 -m pip install gevent
正常的同步调用
from gevent import monkey;monkey.patch_all() # -->这是固定代码,必须得这么写
from gevent import spawn
import time
def play(name):
print('%s play 1' % name)
time.sleep(5)
print('%s play 2' % name)
def eat(name):
print('%s eat 1' % name)
time.sleep(3)
print('%s eat 2' % name)
start = time.time()
play('judy') # 正常的同步调用
eat('judy') # 正常的同步调用
print(('完事儿了 总共%s秒' % (time.time() - start)))
-------------结果---------------

异步提交
from gevent import monkey;monkey.patch_all() # -->这是固定代码,必须得这么写
from gevent import spawn
import time
def play(name):
print('%s play 1' % name)
time.sleep(5)
print('%s play 2' % name)
def eat(name):
print('%s eat 1' % name)
time.sleep(3)
print('%s eat 2' % name)
start = time.time()
g1 = spawn(play, 'judy')
g2 = spawn(eat, 'judy')
g1.join() # 异步提交
g2.join() # 异步提交
print(('完事儿了 总共%s秒' % (time.time() - start)))
-------------结果---------------

协程实现tcp服务端并发的效果
服务端
import socket
from gevent import monkey;
monkey.patch_all()
from gevent import spawn
def talk(conn):
while True:
try:
data = conn.recv(1024)
if len(data) == 0: break
print(data)
conn.send(data + b'judy is nice')
except ConnectionError as e:
print(e)
conn.close()
break
def servers():
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen()
while True:
conn, addr = server.accept()
spawn(talk, conn)
g1 = spawn(servers)
g1.join()
IO模型
Stevens在文章中一共比较了五种IO Model:
* blocking IO
* nonblocking IO
* IO multiplexing
* signal driven IO
* asynchronous IO
由signal driven IO在实际中并不常用,所以主要介绍其余四种IO Model。
🌼 基于网络的数据交互

🌹对于接收方来说有两步:
1、等待数据准备(waiting for data to be ready)
2、将数据从内核拷贝到进程中(copy the data from the kernel to the process)
常见的网络阻塞状态
accept
recv
recvfrom
send虽然有io行为,但是不在我们的考虑范围
阻塞IO
-->我们之前写的都是阻塞IO,协程除外
阻塞IO模型

非阻塞IO

将所有的阻塞操作,全部变为非阻塞
多路服用IO
利用select或者epoll来监管多个程序,一旦某个程序需要的数据存在与内存中了,那么立刻通知程序去取即可
异步IO
只需要发起一次系统调用,之后无需频繁发sing,有结果并准备好之后会通过异步毁掉机制反馈给条用着

前端
一、前端和后端
1、任何与操作系统打交道的界面都可以称之为'前端'
2、不直接与用户打交道,而是控制核心逻辑的运行
二、前端三剑客
| HTML | 网页的骨架,内容(没有样式,很丑) |
|---|---|
| CSS | 网页的样式(给骨架美化) |
| JS | 网页的动态效果(丰富的用户体验) |
三、BS架构
我们在编写TCP服务端的时候,针对客户端的选择可以是总计写的客户端,也可以是浏览器充当客户端也就是bs架构。
我们自己编写的服务端发送的浏览器不识别,原因在于每个人的服务端数据发送的数据格式千差万别,浏览器无法自动识别
所以我们需要一个统一的规范,就是HTTP协议
四、HTTP协议
1、协议:大家商量好的一个共同认可的结果
2、HTTP协议:规定了浏览器与服务端之间数据交互的方式和其他事项
3、🌹四大特性
(1)基于请求响应
服务端永远不会主动给客户端发送消息,必须是客户端先发请请求
如果让服务端给客户端发送消息可以采取其他网络协议
(2)基于TCP,IP用于应用层上的协议
应用层HTTP、传输层、网络层、数据链路层、无力链路层
(3)无状态
不保存客户端的状态信息,早起的网站不需要用户注册,所有人访问的网页数据都是一样的
(4)无链接/短连接
两者请求响应之后立刻断绝关系
4、🌹数据格式
🌼 请求格式
请求首行(网页请求方法)
请求头(k:v 健值对)
(换行符,不能省略)
请求体(并不是所有的请求方法都有)
🌼 响应格式
响应首行(网页请求方法)
响应头(k:v 健值对)
(换行符,不能省略)
响应体(即将交给浏览器的数据)
5、响应状态码
用数字来表示一串中文的意思
1XX 服务端已经接收到了数据正在处理
2XX 200 OK请求成功 服务返回了响应的数据
3XX 重定向(原本想访问A页面,但是自动跳转到了B页面)
4XX 403没有权限访问,404请求资源不存在
5XX 服务器内部错误
"""
公司还会自定义状态码 一般以10000开头
参考:聚合数据
"""
试一试
1、编写服务端
import socket
new_socket=socket.socket()
new_socket.bind(('127.0.0.1',9090))
new_socket.listen()
while True:
conn,addr=new_socket.accept()
while True:
data=conn.recv(1024)
if len(data)==0 : break
print(data)
conn.send(b'hello judy')
2、打开浏览器输入ip端口打开

注意:说明我们的响应体没有做好
3、重新编写
import socket
new_socket=socket.socket()
new_socket.bind(('127.0.0.1',9090))
new_socket.listen()
while True:
conn,addr=new_socket.accept()
while True:
data=conn.recv(1024)
if len(data)==0 : break
print(data)
conn.send(b'HTTP/1.1 200 OK\r\n\r\n')
conn.send(b'hello judy')
conn.send(b'<a href="https://www.jd.com">good see<a>') # 网页地址 / 链接名称
conn.send(
b'<img src="https://imgcps.jd.com/ling4/p-5bd8253082acdd181d02fa06/a677079b/cr/s/q.jpg"/>') #图片地址
浙公网安备 33010602011771号