• 自定义异步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()
  • 相关阅读:
    st-load视频性能测试
    gitlab-ci集成SonarQube代码质量检查
    退役记
    洛谷 P5195 【[USACO05DEC]Knights of Ni S】
    洛谷 P4742 【[Wind Festival]Running In The Sky】
    洛谷 SP13105 【MUTDNA
    洛谷 P3174 【[HAOI2009]毛毛虫】
    洛谷 P1542 【包裹快递】
    Python函数的返回值
    ubuntu18.04修改国内apt源
  • 原文地址:https://www.cnblogs.com/sun-10387834/p/12717572.html
Copyright © 2020-2023  润新知