关于tornado的application和ioloop
2013-02-22 11:03
417 查看
先看一段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分隔的。
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分隔的。
相关文章推荐
- 关于"Server Error in '/' Application"(着急!!!)
- 关于MyEclipse出现错误,在log里看到No Application id found时
- android中关于application的一些东西
- 关于easyui Resource interpreted as Document but transferred with MIME type application/json
- tornado框架源码分析---Application类之debug参数
- struts2关于A web application created a ThreadLocal with key of type 异常解决办法
- [转]tornado ioloop start 的过程
- 关于web中application的配置文件
- 关于tornado-web开发密码加密的使用
- Android开发——Google关于Application Not Responding的建议
- 关于 Content-Type:application/x-www-form-urlencoded 和 Content-Type:multipart/related
- Tornado.web.Application的settings参数
- 以下是computer vision:algorithm and application计算机视觉算法与应用这本书中附录里关于计算机视觉的一些测试数据集和源码站点,我整理了下,加了点中文注解
- 关于tornado中模板的渲染
- 关于application/x-www-form-urlencoded等字符编码的解释说明
- 关于java.lang.ClassNotFoundException: org.springframework.boot.SpringApplication的解决
- Android 用application保存全局变量,关于Android中传递数据的一些讨论
- WPF 图片无法显示……关于Application及SiteOfOrigin的路径问题
- http-关于application/x-www-form-urlencoded等字符编码的解释说明
- android中application 关于全局变量