霍克依毒间

导航

 

先看一段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分隔的。

 

posted on 2013-02-22 11:03  霍克依毒间  阅读(657)  评论(0编辑  收藏  举报