自定義異步IO框架
阿新 • • 發佈:2019-02-04
llb 方法 utf-8 res response sel 異步io header strong
異步 = 非阻塞+循環
select只能完成IO多路復用,不能完成異步
IO多路復用--->監聽多個socket對象,這個過程是同步的
利用其特性可以開發異步模塊
import socket import select class HttpRequest(object): def __init__(self, sk, host, callback): self.socket = sk self.host = host self.callback= callback def fileno(self): # select監聽的對象,只要內部有fileno()方法,並且返回fileno return self.socket.fileno() class HttpResponse(object): def __init__(self, recv_data): self.recv_data = recv_data self.header_dict = {} self.body = None self.initialize()def initialize(self): headers, body = self.recv_data.split(b‘\r\n\r\n‘, 1) self.body = body header_list = headers.split(b‘\r\n‘) for h in header_list: h_str = str(h, encoding=‘utf-8‘) v = h_str.split(‘:‘, 1) if len(v) == 2: self.header_dict[v[0]]= v[1] class AsyncRequest(object): def __init__(self): self.conn = [] self.connection = [] def add_request(self, host, callback): try: sk = socket.socket() sk.setblocking(0) sk.connect((host, 80),) except BlockingIOError as e: pass # 把sk、host和callback封裝起來,返回fd給select request = HttpRequest(sk, host, callback) self.conn.append(request) self.connection.append(request) def run(self): while True: rlist, wlist, elist = select.select(self.conn, self.connection, self.conn, 0.05) for w in wlist: # 只要能循環到,表示socket和服務端已經連接成功 print(w.host, ‘連接成功...‘) tpl = "GET / HTTP/1.0\r\nHost:%s\r\n\r\n" % (w.host,) w.socket.send(bytes(tpl, encoding=‘utf-8‘)) self.connection.remove(w) for r in rlist: recv_data = bytes() while True: try: chunck = r.socket.recv(8096) recv_data += chunck except Exception as e: break # 把返回的數據進行處理,然後交給回調函數 response = HttpResponse(recv_data) r.callback(response) r.socket.close() self.conn.remove(r) if len(self.conn) == 0: break def f1(response): print(‘保存到文件‘,response.header_dict) def f2(response): print(‘保存到數據庫‘, response.header_dict) url_list = [ {‘host‘:‘www.baidu.com‘,‘callback‘: f1}, {‘host‘:‘cn.bing.com‘,‘callback‘: f2}, {‘host‘:‘www.cnblogs.com‘,‘callback‘: f2}, ] req = AsyncRequest() for item in url_list: req.add_request(item[‘host‘],item[‘callback‘]) req.run()
自定義異步IO框架