zoukankan      html  css  js  c++  java
  • tornado和异步IO的基本简单流程原理

    tornado

    #建立连接
    from tornado.httpclient import AsyncHTTPClient
    #发送请求
    from tornado.httpclient import HTTPRequest
    #事件循环
    from tornado import ioloop
    #接收的次数
    REV_COUNTER = 0
    #请求的次数
    REQ_COUNTER = 0
    def handle_response(reponse):
        """
        处理返回值内容(需要维护计数器,来停止IO循环),调用ioloop.IOLoop.current().stop
        :param reponse:
        :return:
        """
        if reponse.error:
            print("Error:",reponse.error)
        else:
            print(reponse.body)
        global REV_COUNTER
        REV_COUNTER+=1
        if REV_COUNTER == REQ_COUNTER:
            print(REQ_COUNTER)
            ioloop.IOLoop.current().stop()
    
    def func():
        url_list = [
            'http://www.baidu.com',
            'http://www.bing.com',
        ]
        global REQ_COUNTER
        REQ_COUNTER = len(url_list)
        for url in url_list:
            print(url)
            #建立连接
            http_client = AsyncHTTPClient()
            #发送请求,handle_response是回调函数
            http_client.fetch(HTTPRequest(url),handle_response)
    #添加函数,事件循环
    ioloop.IOLoop.current().add_callback(func)
    #获取响应结果,事件循环
    ioloop.IOLoop.current().start()
    

    异步IO的基本简单流程原理

    #实现异步的基本流程
    import socket
    import select
    req_list =[
        ["1.1.1.1",80],
        ["1.1.1.2",80],
    ]
    conn_sock_list = []
    sock_list = []
    for i in req_list:
        client = socket.socket()
        #不等待
        client.setblocking(False)
        try:
            client.connect(i[0],i[1],)
        except Exception as e:
            pass
        sock_list.append(client)
        conn_sock_list.append(client)
    
    while True:
        #IO的多路复用同步
        r,w,e = select.select(sock_list,conn_sock_list,[],1)
        #当其他人给咱们发送数据时候,我们可以接收r=[sk1]
        for sk in r:
            try:
                #接收8096数据,因为不知道接收到的数据是否都是8096字节的,所以得循环去接收
                while True:
                    data = sk.recv(8096)
                    if not data:
                        sock_list.remove(sk) #当数据为空时候,http是短链接,接收到返回的数据http断开,不会接收到任何数据,数据接收完不再接收把之前获取到的数据移除
            except Exception as e:
                pass
        #连接成功的socket,可以有下一步的进展
        for sk in w:
            sk.sendall("""GET /index HTTP/1.0
    Host:www.baidu.com
    
    """)
            #已经发送过的请求在socket删除
            conn_sock_list.remove(sk)
        if not sock_list:
            break
    

    上面的异步IO有一个缺陷就是没有保存获取响应结果的数据,可以新建一个类来解决这个问题

    #实现异步的基本流程
    import socket
    import select
    
    class HttpContext(object):
        def __init__(self,sock):
            #client
            self.sock = sock
            #保存数据
            self.buffer = []
    
        def fileno(self):
            return self.sock.fileno
    
    
    req_list =[
        ["1.1.1.1",80],
        ["1.1.1.2",80],
    ]
    conn_sock_list = []
    sock_list = []
    for i in req_list:
        client = socket.socket()
        #不等待
        client.setblocking(False)
        try:
            client.connect(i[0],i[1],)
        except Exception as e:
            pass
        obj = HttpContext(client)
        sock_list.append(obj)
        conn_sock_list.append(obj)
    
    while True:
        #IO的多路复用同步
        #r,w,e = select.select([socket.fileno,socket]->[HttpContext.fileno,HttpContext],conn_sock_list,[],1)
        r,w,e = select.select(sock_list.fileno,conn_sock_list,[],1)
        #当其他人给咱们发送数据时候,我们可以接收r=[sk1]
        for sk in r:
            try:
                #接收8096数据,因为不知道接收到的数据是否都是8096字节的,所以得循环去接收
                while True:
                    data = sk.sock.recv(8096)
                    #保存数据
                    obj.buffer.append(data)
                    if not data:
                        sock_list.remove(sk) #当数据为空时候,http是短链接,接收到返回的数据http断开,不会接收到任何数据,数据接收完不再接收把之前获取到的数据移除
            except Exception as e:
                pass
        #连接成功的socket,可以有下一步的进展
        for sk in w:
            sk.sock.sendall("""GET /index HTTP/1.0
    Host:www.baidu.com
    
    """)
            #已经发送过的请求在socket删除
            conn_sock_list.remove(sk)
        if not sock_list:
            break
    
  • 相关阅读:
    Maven:mvn 命令的基本使用
    Java:SPI机制
    Bootstrap3 排版-内联文本元素
    Bootstrap3 排版-页面主体
    Bootstrap3 排版-标题
    Bootstrap3 栅格系统-Less mixin 和变量
    Bootstrap3 栅格系统-列排序
    Bootstrap3 栅格系统-嵌套列
    Bootstrap3 栅格系统-列偏移
    Bootstrap3 栅格系统-实例:响应列重置(Responsive column resets)
  • 原文地址:https://www.cnblogs.com/venvive/p/11657932.html
Copyright © 2011-2022 走看看