前端简介/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)))

-------------结果---------------
image

异步提交

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)))

-------------结果---------------
image

协程实现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。

🌼 基于网络的数据交互
image
🌹对于接收方来说有两步:
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模型
image

非阻塞IO

image
将所有的阻塞操作,全部变为非阻塞

多路服用IO

利用select或者epoll来监管多个程序,一旦某个程序需要的数据存在与内存中了,那么立刻通知程序去取即可

异步IO

只需要发起一次系统调用,之后无需频繁发sing,有结果并准备好之后会通过异步毁掉机制反馈给条用着
image

前端

一、前端和后端

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端口打开
image
注意:说明我们的响应体没有做好

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"/>') #图片地址
posted @ 2022-01-17 19:08  JudyJU  阅读(166)  评论(0)    收藏  举报