自定义异步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"\r\n\r\n",1) 26 self.body=str(body,encoding="utf-8") 27 v=str(headers,encoding="utf-8").split("\r\n") 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\r\nHost:%s\r\n\r\n" % (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()