• 关于tornado的application和ioloop


    先看一段torando的示例程序

    import tornado.ioloop
    import tornado.web
     
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.write("Hello, world")
     
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
     
    if __name__ == "__main__":
        application.listen(8000)
        tornado.ioloop.IOLoop.instance().start()
     
    可以看出tornado运行其实是分为两段的。一段是application,是关于应用的。一段是ioloop是关于网络io的。
    首先看一下应用这一段。跟踪一下application.listen(8000)这行代码。
    web.py的1176行有对Application类的listen函数的定义。在这里面调用了HTTPServer类的listen函数。
    HTTPServer定义在httpserver.py,他继承自TCPServer,然后没对listen函数做操作。所以Application其实是直接调用的TCPServer的listen函数。
    netutil.py的92行TCPServer的listen调用了bind_sockets。参数是port(8000,传进来的)和address("",默认的)。
    netutil.py的220行,定义了bind_sockets。他调用了getaddrinfo得到了本地建立socket的一些信息。包括socket通信域、socket类型、socket协议等等。然后建立socket,并且把这个socket返回。其实在这个时候,服务器端的网络监听已经建立完成了。
    然后回到netutil.py92行的listen函数里。在这里调用了add_sockets,并且将刚才返回的额socket传给了他。在add_sockets里面首先会生成一个ioloop对象,又调用了add_accept_handler,并且把这个ioloop对象和TCPServer的_handle_connection函数作为call_back传给了它。在add_accept_handler里面,调用之前生成的ioloop对象的add_handler函数,这次加的handler相当于是 加上了对数据的接收,在这里面调用了socket.accept。
     
    然后再看 tornado.ioloop.IOLoop.instance().start()这一行代码
    在这里tornado.ioloop.IOLoop.instance()得到的就是之前一行代码里声称的ioloop对象
    ioloop.py的230行左右有对start函数定义。当有请求来的时候,epoll会往下走。在start函数的最后有self._handlers[fd](fd, events),其实就是调用了前面分析的_handle_connection这个call_back。
    _handle_connection会调用handle_stream来处理来的请求内容。因为HTTPServer类继承自TCPServer类,并且改写了handler_stream函数,所以调用的其实是HTTPServer类的handler_stream(之前调用的也都是HTTPServer类的,只不过 HTTPServer的函数都是继承下来的,所有都是在其他类的代码文件里面看的代码)。
    在HTTPServer类的handler_stream里面,生成了一个HTTPConnection对象。
    在HTTPConnection类的构造函数里面,有self.stream.read_until(b("\r\n\r\n"), self._header_callback)。说明tornado解析http格式的报文,只能解析报文头以\r\n\r\n结束的,不能解析以\n\n结束的。并且调用_head_callback来解析http报头
    在HTTPConnection类的构造函数里面,有self._header_callback = stack_context.wrap(self._on_headers)。
    在_on_headers函数是解析http协议头的各个字段的。在这里面有eol = data.find("\r\n")。说明tornado解析http格式报文头的各个字段,只能解析以\r\n分隔的,不能解析以\n分隔的。

     

  • 相关阅读:
    angular的路由例子
    angular自定义module
    docker配置phpadmin需要注意的地方
    linux下钉钉,微信
    debian shell脚本关联
    debian下安装带界面的qemu
    ros的一些设置
    新闻排重方案设计
    细解动态规划(一)
    漫画谈-微积分(二)
  • 原文地址:https://www.cnblogs.com/lddhbu/p/2921930.html
Copyright © 2020-2023  润新知