Python之路PythonNet,第四篇,网络4
pythonnet 网络4
select 支持水平触发
poll 支持水平触发
epoll
epoll 也是一种IO多路复用的方式,效率比select和poll 要高一点;
epoll 不仅支持水平触发也支持边缘触发;
循环服务器模型;
并发服务器模型;
IO多路复用模型;
协程服务器模型;
#######################
协程(微线程,纤程) 本质单线程
定义: 是一种用户态的轻量级线程;
特点:1, 轻量级,创建消耗资源非常少; 2,不涉及内核;
优点:(1) 无需上下文切换的开销;
(2)无需同步互斥操作;
(3)有较高的并发性(IO并发);
(4)创建消耗资源少;
缺点:(1) 无法利用计算机的多核资源
(2)遇到死循环等阻塞状态会影响整个程序的运行;
greenlet
sudo pip3 install greenlet
gevent
sudo pip3 install gevent
练习1
greenlet
from greenlet import greenlet #协程函数
def test1():
print(111111111)
gr2.switch()
print(222222222)
gr2.switch() def test2():
print(333333333)
gr1.switch()
print(444444444) #讲函数变为协程
gr1 = greenlet(test1)
gr2 = greenlet(test2)
gr1.switch() #自动运行gr1
#########
# python3 greenlet_demo.py
1111111111
3333333333
2222222222
4444444444
gevent
import gevent
import time #协程函数
def foo(a,b):
print("Running in foo",a,b)
gevent.sleep(3) #模拟遇到IO阻塞的情况(秒)
print('switch to foo again') def bar():
print("Running in bar")
gevent.sleep(2)
print("switch to bar again") #注册为协程事件
f = gevent.spawn(foo,1,2)
b = gevent.spawn(bar) # gevnet.join(f)
# gevnet.join(b)
gevent.joinall([f,b])
###########
# python3 gevent_demo.py
Running in foo 1 2
Running in bar
switch to bar again
switch to foo again
协程高并发
import gevent
#monkey 脚本插件的使用要在导入socket之前
#它改变了socket模块的阻塞部分
from gevent import monkey
monkey.patch_all()
from socket import * #协程事件
def handler(c,addr):
print("Connect from",addr)
while True:
data = c.recv(1024).decode()
if not data:
break
print("Recv msg:",data)
c.send(b"Receive your message")
c.close() HOST = '172.60.50.218'
PORT = 9999
ADDR = (HOST,PORT)
s = socket()
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(ADDR)
s.listen(20) while True:
c,addr = s.accept()
gevent.spawn(handler,c,addr) s.close()
进程 + 协程方案完成高并发
1,什么是协程(单线程, 优点缺点,高并发量的IO操作)
2, 协程是如何工作的 (是在线程栈中进行跳转,是应用层技术,遇到IO阻塞进行协程选择)
3, 写过什么协程代码
非阻塞IO和超时检测
定义:非阻塞IO是在遇到原本阻塞的IO情形时,不进行阻塞等待;如果满足执行条件即执行,不满足条件就不执行;
sockfd.setblocking(False)
功能:设置一个套接字的阻塞状态;
参数: 默认为True,表示套接字为阻塞套接字;
如果设置为False,则表示非阻塞, 此时套接字使用阻塞函数时,如果无法正常执行,则抛出blocking异常;
说明:监听套接字设置为非阻塞,则accept不再阻塞;
连接套接字设置为非阻塞,则recv不再阻塞;
超时检测
在状态下,设置程序超时时间。当达到时间后进程不再阻塞等待;
例:multiprocessing/threading ----> join
Queue -----> get 、 put
select -----> select
Event -----> wait
sockfd.settimeout(5)
功能: 设置套接字的超时检测事件;
参数:超时时间
from socket import *
import time HOST = '172.60.50.218'
PORT = 8888
ADDR = (HOST,PORT)
BUFFERSIZE = 1024 sockfd = socket(AF_INET,SOCK_STREAM)
sockfd.bind(ADDR)
sockfd.listen(5) #将sockfd 变为非阻塞
# sockfd.setblocking(False) #设置sockfd 的超时时间
sockfd.settimeout(5) while True:
print("wait for connect......")
# time.sleep(8)
#套接字等待客户端请求
try:
conn,addr = sockfd.accept()
print("connect from ",addr)
# conn.setblocking(False)
while True:
data = conn.recv(BUFFERSIZE)
if not data:
break
print("接受到:",data.decode())
n = conn.send(b"Recv your message\n")
print("发送了 %d 字节的数据"%n)
conn.close()
except Exception as e:
print(e) sockfd.close()
网络广播(是一端发送,多端接收的模式)
udp数据报套接字
广播地址:192.168.1.255
设置套接字为可以发送接收广播的套接字;
s.setsockopt(SOL_SOCKET,SO_BROADCAST,1)
*在网络中如果存在大量的广播会产生广播风暴,占用大量带宽;
#########recv############ from socket import * HOST = ''
PORT = 9999 #使用数据报套接字
s = socket(AF_INET,SOCK_DGRAM) #设置套接字为允许广播
s.setsockopt(SOL_SOCKET,SO_BROADCAST,1) s.bind((HOST,PORT)) while True:
try:
message,addr = s.recvfrom(1024)
print('get msg from',addr)
print("广播通知:",message.decode())
s.sendto('收到广播了'.encode(),addr)
except Exception as e:
print(e)
s.close() #########sendto#######
from socket import *
from time import sleep #设置发送的广播地址 , <broadcast>
dest = ('172.60.50.255',9999) s = socket(AF_INET,SOCK_DGRAM) s.setsockopt(SOL_SOCKET,SO_BROADCAST,1) while True:
sleep(2)
s.sendto("喜迎两会,习大大带你飞".encode(),dest)
data,addr = s.recvfrom(1024)
print(data.decode()) s.close()
本地套接字:
作用:用作本地两个进程间的通信;
传输方式: 字节流的方式进行数据传输;
创建本地套接字: socket(AF_UNIX,SOCK_STREAM)
通信介质:通过套接字文件实现通信;
########unix_recv####### from socket import *
import os #设置通信的套接字文件
address = './sockfile' try:
os.unlink(address) #删除这个目录下的这个文件
except OSError:
if os.path.exists(address): #判断文件是否删除成功
raise s = socket(AF_UNIX,SOCK_STREAM)
s.bind(address) #绑定本地套接字的文件
s.listen(5) while True:
conn,addr = s.accept()
print("connect from",addr) #addr是空子串
while True:
data = conn.recv(1024).decode()
if not data:
break
print("receive:",data)
conn.send(b"receive your message")
conn.close()
s.close() #########unix_send#########
from socket import *
from time import sleep address = './sockfile' s = socket(AF_UNIX,SOCK_STREAM) try:
s.connect(address)
except error as e:
print(e) try:
message = b"This is a unix message"
s.send(message)
# sleep(20)
data = s.recv(1024).decode()
print('recv:',data)
except error as e:
print(e)
finally:
s.close()
http超文本传输协议
应用层协议---> 传输层使用TCP协议
用途:网站中网页的传输数据的传输;也可以用作通过编程传输数据;
http协议特点:
(1)支持典型的客户端服务器模式;
(2)灵活简单;
(3)几乎支持所有的数据格式;
(4)是无状态的;
(5)http1.0无连接, http1.1持续连接
1,请求
(1)请求格式:
2,请求行:发送什么类型的请求
3,请求头:对发送请求信息的描述
空行
4,请求体:具体的请求参数或请求内容;
GET /index.html HTTP/1.1
请求方法 请求格式 协议版本
GET :获取URL标识网络资源(url统一资源定位符,指的是网络资源在网络中的位置,网址即为一类的url)
POST : 提交一定的附加数据,用以获取相应的返回;
HEAD 获取URL所标识的相应消息报头;
PUT: 获取服务器的资源;
DELETE 删除一个服务器资源;
TRACE :用于测试和诊断;
CONNECT :保留的请求方法;
OPTIONS : 请求获取服务器性能,查询相关资源信息;
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.5
Cache-Control: max-age=0
Connection: keep-alive
Cookie: BAIDUID=087384E8032769651B65AEC1E9FC1683:FG=1; BIDUPSID=087384E8032769651B65AEC1E9FC1683; PSTM=1517361569; BD_UPN=133352; BD_HOME=0; H_PS_PSSID=1460_21118_17001_22160
Host: www.baidu.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0
请求体:
a:3 b:4
get请求:请求体即为get请求的参数;
post请求:请求即为post请求提交的内容;
相应:
格式
1,相应行: 反馈响应情况;
2,响应头:对响应内容的描述;
3,空行;
4,响应内容: 根据请求返回给客户端的内容;
HTTP/1.1 200 OK
协议版本 响应码 响应码对应信息
1xx :提示信息,表示请求已经接受,正在处理;
2xx : 访问成功;
3xx : 重定向,完成任务需要其他操作;
4xx : 客户端错误;
5xx : 服务器端错误;
例:
200 访问成功;
400 客户端请求有语法错误; 401 访问没有权限; 403 服务器已收到请求,但是拒绝执行; 404 请求的服务器资源不存在;
500 服务器发生未知错误; 503 服务器暂时不能执行,请稍后访问再试;
Bdpagetype: 1
Bdqid: 0xbccf8ff30001ca5b
Bduserid: 0
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Cxy_all: baidu+7f98f395ebbdb0df7ebccec435f56c3f
Date: Mon, 26 Mar 2018 08:30:45
相应体 就是给客户端返回的内容;
总结:
(1)什么是HTTP协议;
(2)http协议请求和相应的格式;
(3)请求方法都有哪些;
(4)常见的相应码代表什么;
(5)get请求和post请求区别;
(6)http协议的特点;
模块:
python http server
python2 BaseHTTPserver
python3 http.server
HTTPSERVER 服务器用来接收客户端的HTTP请求;
#导入HTTPSERVER类 兼容python3 and python2
try:
from BaseHTTPServer import \
BaseHTTPRequestHandler,HTTPServer
except ImportError:
from http.server import \
BaseHTTPRequestHandler,HTTPServer #具体的请求处理类
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
print("do method get")
fd = open('index.html','rb')
content = fd.read()
#设置响应码
self.send_response(200)
#设置响应头
self.send_header('Content-type','text/html')
#响应头设置完毕
self.end_headers()
#发送响应体
self.wfile.write(content)
return def do_POST(self):
pass #搭建启动服务器
address = ('127.0.0.1',8000)
server = HTTPServer(address,RequestHandler)
server.serve_forever()
Python之路PythonNet,第四篇,网络4的更多相关文章
- Python之路PythonNet,第一篇,网络1
pythonnet 网络1 ARPAnet(互联网雏形)---> 民用 ISO(国际标准化组织)--->网络体系结构标准 OSI模型 OSI : 网络信息传输比较复杂需要很多功能协同 ...
- Python之路PythonNet,第二篇,网络2
pythonnet 网络2 问题: 什么是七层模型tcp 和udp区别三次握手和四次挥手************************************************** tcp ...
- Python之路【第四篇】:Python基础之函数
函数的理解 面向过程:根据业务逻辑从上到下垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 函数作用是你的程序有良好的扩展性.复用性. 同样的功能要是用3次以上的话就建议使 ...
- Python之路(第三十三篇) 网络编程:socketserver深度解析
一.socketserver 模块介绍 socketserver是标准库中的一个高级模块,用于网络客户端与服务器的实现.(version = "0.4") 在python2中写作S ...
- Python之路(第三十篇) 网络编程:socket、tcp/ip协议
一.客户端/服务器架构 1.硬件C/S架构(打印机) 打印机作为一个服务端,电脑连接打印机进行打印 2.软件C/S架构 互联网中处处是C/S架构 如谷歌网站是服务端,你的浏览器是客户端(B/S架构也是 ...
- Python之路【第四篇】: 函数、递归、内置函数
一. 背景提要 现在老板让你写一个监控程序,监控服务器的系统状况,当cpu\memory\disk等指标的使用量超过阀值时即发邮件报警,你掏空了所有的知识量,写出了以下代码 while True: i ...
- Python之路【第四篇】:模块
什么是模块: 模块就是一个功能的集合. 模块就和乐高积木差不多,你用这些模块组合出一个模型,然后也可以用这个模块加上其他的模块组合成一个新的模型 模块的种类: 1.内置模块(python自带的比如os ...
- 【Python之路】第四篇--Python基础之函数
三元运算 三元运算(三目运算),是对简单的条件语句的缩写 # 书写格式 result = 值1 if 条件 else 值2 # 如果条件成立,那么将 “值1” 赋值给result变量,否则,将“值2” ...
- Python之路(第三十一篇) 网络编程:简单的tcp套接字通信、粘包现象
一.简单的tcp套接字通信 套接字通信的一般流程 服务端 server = socket() #创建服务器套接字 server.bind() #把地址绑定到套接字,网络地址加端口 server.lis ...
- Python之路【第四篇补充】:面向对象初识和总结回顾
面向过程的编程 面向过程:根据业务逻辑从上到下写垒代码! 例子: 需求一.有一个程序需要做身份认证: 用户名有个字典: #定义一个用户名信息字典 user_info = { "zhangsa ...
随机推荐
- Hadoop--单点故障修复
nameNode单点故障修复 1.启动虚拟机,启动集群 此时我们将主机hadoop1关机(断掉主机),开始抢救: 1.使用 秘书(secondaryNameNode),成功率不是100% (这里我 ...
- js中用来操作数组的相关的方法
push向数组的的末尾添加新的内容 unshift向数组的开头增加新的内容 slice(n,m)从索引n开始(包含n),找到索引m处(不包含m),然后把找到的内容作为一个新的数组返回,原有的数组不改变 ...
- Qt绘制字体并获取文本宽度
参考资料: https://blog.csdn.net/liang19890820/article/details/51227894 QString text("abc");QPa ...
- unity中制作模拟第一人称视角下的指南针
private int zRotation; public GameObject obj; public void Update() { //obj = GameObject.Find("C ...
- hdu1693
题解: 还是插头dp 代码: #include<cstdio> #include<cstring> #include<algorithm> #include< ...
- day21-python操作mysql1
python的mysql操作 mysql数据库是最流行的数据库之一,所以对于python操作mysql的了解是必不可少的.Python标准数据库接口为Python DB-API, Python DB- ...
- [HDU3436]Queue-jumpers
Problem 有一个数列,从1排列到n,然后有Q个操作 Top x:将第x个数放到序列的最前面 Query x:询问x这个数在第几位 Rank x:询问第x位数是什么 Solution n非常的大, ...
- JavaScript -基础- 函数与对象
一.JavaScript三对象 1.分类方式一 1)ECMAScript JavaScript的ECMA规范 JS本身的对象 2)Dom 操作HTML相关 3)BOM游览器对象 游览器窗口对象,全局的 ...
- asp.net webform 不显示__doPostBack的原因及某种解决方法
为了维护老旧的asp.net webform系统,今天发现一个问题:asp.net页面没有自动生成__doPostBack方法,提示该js方法不存在.于是在网上找了大量的方法,基本上都说是IE的问题, ...
- Comparable和Comparator接口是干什么的?列出它们的区别。
Comparable和Comparator接口是干什么的?列出它们的区别. Java提供了只包含一个compareTo()方法的Comparable接口.这个方法可以个给两个对象排序.具体来说,它返回 ...