自定义异步IO框架

 1 # __author__:Kelvin
 2 # date:2020/4/16 21:55
 3 import socket
 4 import select
 5 
 6 #-------------------自定义异步IO框架内容-------------------------
 7 #用来封装socket对象,host,和回调函数
 8 class HttpRequest:
 9     def __init__(self, sk, host, callback):
10         self.socket = sk
11         self.host = host
12         self.callback = callback
13 
14     def fileno(self):
15         return self.socket.fileno()
16 
17 #用来封装服务器响应内容
18 class HttpResponse:
19     def __init__(self,recv_data):
20         self.recv_data=recv_data
21         self.header={}
22         self.body=None
23         self.initial()
24     def initial(self):
25         headers,body=self.recv_data.split(b"

",1)
26         self.body=str(body,encoding="utf-8")
27         v=str(headers,encoding="utf-8").split("
")
28         for i in v:
29             item=i.split(":",1)
30             if len(item) ==2:
31                 self.header[item[0]]=item[1]
32             elif len(item)==1:
33                 self.header["method"]=item[0]
34 
35 #异步IO实现类
36 class AsycnRequest:
37     def __init__(self):
38         self.conn = []
39         self.connection = []
40 
41     def add_request(self, host, callback):
42         try:
43             sk = socket.socket()
44             sk.setblocking(0)
45             sk.connect((host, 80))
46         except BlockingIOError as e:
47             pass
48         request = HttpRequest(sk, host, callback)
49         self.conn.append(request)
50         self.connection.append(request)
51 
52     def run(self):
53         while True:
54             rlist, wlist, elist = select.select(self.conn, self.connection, self.conn, 0.5)
55             for w in wlist:
56                 print(w.host, "连接成功...")
57                 tpl = "GET / HTTP/1.1
Host:%s

" % (w.host,)
58                 w.socket.send(bytes(tpl, encoding="utf-8"))
59                 self.connection.remove(w)
60             for r in rlist:
61                 recv_data = bytes()
62                 while True:
63                     try:
64                         chunck = r.socket.recv(8096)
65                         recv_data += chunck
66                     except Exception as e:
67                         break
68                 response=HttpResponse(recv_data)
69                 r.callback(response)
70                 r.socket.close()
71                 self.conn.remove(r)
72             if len(self.conn) == 0:
73                 break
74 
75 
76 
77 #-------------------用户使用框架内容-------------------------
78 #用户自定义回调函数
79 def f1(response):
80     print("保存在硬盘中...",response.header,response.body)
81 
82 def f2(response):
83     print("保存在数据库中...",response.header,response.body)
84 
85 #用户想要请求的host列表
86 url_list = [
87     {"host": "www.baidu.com", "callback": f1},
88     {"host": "cn.bing.com", "callback": f2},
89     {"host": "www.cnblogs.com", "callback": f2},
90 ]
91 #创建异步IO类
92 asycn_obj = AsycnRequest()
93 #调用add_request方法,生成若干个socket对象,放在两个列表conn和connection中
94 for url in url_list:
95     asycn_obj.add_request(url["host"], url["callback"])
96 #调用run方法创建select,监听多个socket,并对响应的socket进行处理
97 asycn_obj.run()
原文地址:https://www.cnblogs.com/sun-10387834/p/12717572.html