美文网首页
使用python编写一个异步非阻塞模块

使用python编写一个异步非阻塞模块

作者: 万越天 | 来源:发表于2018-02-06 10:46 被阅读0次

    异步IO请求的本质则是【非阻塞Socket】+【IO多路复用】

    #!/usr/bin/env python
    # _*_ encoding:utf-8 _*_
    
    import socket
    import select
    
    
    class Reqest:
        def __init__(self, sk, info):
            self.sk = sk
            self.info = info
    
        def fileno(self):
            return self.sk.fileno()
    
    
    class AsyncMod:
        def __init__(self):
            self.sk_list = []
            self.conns = []
    
        def add_request(self, req_info):
            """
            创建请求
            :return: 
            """
            sk = socket.socket()
            sk.setblocking(False)
            try:
                sk.connect((req_info["host"], req_info["port"]))   # 连接的请求已经发出去了
            except BlockingIOError as e:
                pass
            obj = Reqest(sk, req_info)
            self.sk_list.append(obj)
            self.conns.append(obj)
    
        def run(self):
            """
            开始事件循环,检测连接是否成功,数据是否返回?
            :return: 
            """
            while True:
                # select.select([socket对象])
                # 不一定是socket对象,可是任何任何对象,对象一定要有fileno方法
                r, w, e = select.select(self.sk_list, self.conns, [], 0.05)
                # 是否连接成功
                for obj in w:
                    # 检查obj是哪个字典
                    data = "GET %s http/1.1\r\nhost:%s\r\n\r\n" % (obj.info["path"], obj.info["host"])
                    # print(data)
                    obj.sk.send(data.encode("utf-8"))
                    self.conns.remove(obj)
                # 数据返回,接收到数据
                for obj in r:
                    response = obj.sk.recv(8096)
                    print(obj.info["host"], response)
                    obj.info["callback"](response)
                    self.sk_list.remove(obj)
                # 所有的请求已经返回
                if not self.sk_list:
                    break
    
    
    def done(response):
        print(response)
    
    
    url_list = [
        {"host": "www.baidu.com", "port": 80, "path": "/", "callback": done},
        {"host": "www.cnblogs.com", "port": 80, "path": "/", "callback": done},
        {"host": "www.bing.com", "port": 80, "path": "/", "callback": done},
    ]
    
    am = AsyncMod()
    for item in url_list:
        am.add_request(item)
    
    am.run()
    

    相关文章

      网友评论

          本文标题:使用python编写一个异步非阻塞模块

          本文链接:https://www.haomeiwen.com/subject/autgzxtx.html