一.osi七层模型
应用层 http https ssl smtp ftp
表示层,会话层
传输层 tcp udp 端口信息 四层路由器 四层交换机
# tcp
# 可靠的 面向连接的 全双工的 流式传输 效率低
# 三次握手和四次挥手
# 三次握手
# 把图背下来 syn ack
# 四次挥手
# 把图背下来 fin ack
# 黏包 : (自定义协议)先发送数据的长度,再发送数据
# udp 效率高 不可靠 无连接 基于数据包的传输 能够传输的数据的长度有限
网络层 ipv4协议192.168.0.1 ipv6协议 ff2312:f5242:12:1:1:1 网关地址 子网掩码 路由器 三层交换机
数据链路层 :arp (通过ip地址找到mac地址),rarp(通过mac地址找ip地址) 网卡 交换机
物理层
三次握手,四次挥手
有syn ack fin 三种
手写socket
# 手写socket # server - tcp import socket # sk = socket.socket() # sk.bind(('127.0.0.1',9000)) # sk.listen() # # # while True表示能够和多个client通信 # conn,adds = sk.accept() # 建立三次握手的过程 # # while True表示能够和一个client说多句话 # conn.recv(1024) # conn.send(b'xxx') # conn.close() # sk.close() # 四次挥手中的两手 # client -tcp # import socket # sk = socket.socket() # sk.connect(('127.0.0.1',9000)) # # sk.send(b'hello') # sk.recv(1024) # sk.close() # 四次挥手中的两手 # server -udp # import socket # sk = socket.socket(type=socket.SOCK_DGRAM) # sk.bind(('127.0.0.1',9000)) # while True: # msg,cli_addr = sk.recvfrom(1024) # sk.sendto(msg,cli_addr) # sk.close() # clients -udp # import socket # sk = socket.socket(type=socket.SOCK_DGRAM) # sk.sendto(b'msg',('127.0.0.1',9000)) # msg,_ = sk.recvfrom(1024) # print(msg) # sk.close()
操作系统:
异步同步阻塞非阻塞并发并行
并发和并行
并行 能利用多核 同一时刻 有多个任务在CPU上同时执行 多任务
并发 不能利用多核 同一时间段内 有多个任务在一个CPU上轮流被执行 一个cup一直使用
同步和异步
同步 当我执行一个任务 需要等待这个任务的结果才能继续执行下一个任务
异步 当我执行某一个任务 不需要等待这个任务的结果 就可以继续执行下一个任务
阻塞和非阻塞
非阻塞 : cpu一直在工作
阻塞 : CPU不工作 recv recvfrom accept input sleep
io操作
input : input read recv recvfrom accept connet close
output: write send sendto connet accept close
# 同步阻塞 等待不调度cup # def func(): # import time # time.sleep(1) # # def func2(): # func() # print(123) # func2() # 同步非阻塞 等待调度cup # def func(): # a = 1 # b= a+1 # return b # def func2(): # func() # print(123) # func2() # 异步阻塞 不等待不调度cup # import time # import threading # def func(): # time.sleep(1) # t_l = [] # for i in range(10): # t = threading.Thread(target=func) # t.start() # t_l.append(t) # for t in t_l:t.join() # 异步非阻塞 # 我调用一个函数 不等待这个函数的结果 # 并且我能一直利用cpu
异步非阻塞:
异步:不等待结果
非阻塞:一致调度cpu
关于io多路复用
作用:在windows中通过select 进行监控 linux 下通过pool epool监控
# 操作系统中的IO多路复用
# select poll epoll
# select windows
# poll epoll linux
# epoll最好
# io多路复用
# 代理所有的网络对象,帮助我们监听有哪一个对象发生了注册事件(读写异常),然后通知程序,去进行相应的处理
# selectors模块
# 能够有效的利用poll和epoll前提是你所在的操作系统是有这两个机制的
# 自动的识别当前操作系统中我们能用的最好的机制
select模块使用
from socket import * import selectors sel=selectors.DefaultSelector() def accept(sk,mask): conn,addr=sk.accept() sel.register(conn,selectors.EVENT_READ,read) def read(conn,mask): try: data=conn.recv(1024) if not data: print('closing',conn) sel.unregister(conn) conn.close() return conn.send(data.upper()+b'_SB') except Exception: print('closing', conn) sel.unregister(conn) conn.close() sk=socket(AF_INET,SOCK_STREAM) sk.bind(('127.0.0.1',8088)) sk.listen(5) sk.setblocking(False) sel.register(sk,selectors.EVENT_READ,accept) #相当于网select的读列表里append了一个文件句柄server_fileobj,并且绑定了一个回调函数accept while True: events=sel.select() # 代理在这里等待,等events事件来,一旦等来了 那么一定是有新的链接 来 或者是有发送给conn的数据来 for sel_obj,mask in events: callback=sel_obj.data #callback=accpet/read callback(sel_obj.fileobj,mask) #accpet(server_fileobj,1)
# select 只能使用select
# selector 能用select poll epoll
# select 采用轮询,能够处理的对象的个数有限
# poll 采用轮询,能够处理的对象的个数无限的
# epoll 回调
# TCP协议
# 监听多个sk,conn对象,谁的数据先来,我就通知谁来处理
# 好处是什么
# 把很个等待变成一个等待,有一个代理替我们来接收所有的请求
线程/进程/协程
在正常的编程语言中
进程 是计算机中最小资源分配单位
数据隔离 开销(开启 销毁 切换)大 内存级别数据安全 但是文件操作数据库操作数据不安全
manager : 数据共享
IPC(inter process communication):队列消息队列memcache
abbitmq
edis
管道 : 基于socket + pickle
原生的queue : 基于文件(管道 + 锁)
第三方工具 : 基于网络稳定性更强
线程 计算机中能被CPU调度的最小单位
数据共享 开销(开启 销毁 切换)小 数据不安全 数据共享程序可能会同时去操作一个变量
协程 本质是一条线程 协程任务对于操作系统来说不可见 协程是用户级的单位
数据共享 开销非常小(函数的调用的速度一样快) 数据绝对安全
在Cpython解释器下
进程
线程 不能利用多核 (flask django) : 文件操作更快
GIL锁 : 全局解释器锁,锁的是线程,保证了同一个进程中的多个线程之间只有一个线程能访问CPU
限制了一个python进程中的多线程不能利用多核
无法处理高计算型的任务
解决方案 开多进程
协程(tonado tiwsted sanic scrapy) : 所有的time.sleep socket 协程更快
一条线程
指的是程序能够在多个协程任务之间来回切换
如果在程序中遇到io就切换去执行另一个程序,实现了使用协程来规避io,提高cpu的使用率
yield协程
# def func(): # yield 1 # print(123) # yield 2 # def func2(): # g = func() # g.__next__() # asyncio 基于yield关键字gevent 基于greenlet来完成的 # aiohttp