博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

TCPServer模块建立、监听、接受socket。每创建一个连接,都将对应的socket加入到ioloop的监听队列中,并且将socket包装成一个IOStream对象,该对象提供了异步读写socket的功能。

处理完成后一个IOStream对象就是一个来自客户端的连接,TCPServer会调用handle_stream()函数处理该对象,这也是本层与上层的接口。

 

1、创建套接字,绑定IP、端口,开始监听,由tornado.netutil.bind_sockets  函数完成

def bind_sockets():
    sock = socket.socket() #创建套接字
    sock.setblocking(0)      #设置套接字为非阻塞模式
    sock.bind(sockaddr)     #为套接字绑定IP、port
    sock.listen()                 #开始监听
return sock

2、将套接字添加至IOLoop,并设置回掉函数,由tornado.TCPServer.TCPServer.listen  函数完成

class TCPServer(object):
    def listen(self, port, address=""):
        sock = bind_sockets(port, address=address)
        self.add_sockets(sock)

    def add_sock(self, sock):
        if self.io_loop is None:
            self.io_loop = IOLoop.current()  #IOLoop是个单例模式的类,通过该方法获取实例
        
        #将sock添加至ioloop的监听列表,并且设置回掉函数为self._handle_connection,当sock中有tcp请求时,ioloop调用该回调函数
        add_accept_handler(sock, self._handle_connection, io_loop=self.io_loop)

3、当sockt中有tcp请求时,ioloop调用回调函数TCPServer._handle_connection,在该函数中会accept TCP请求,然后将与客户端连接的scokt包装成一个iostrean(提供各种异步读取sockt的方法),最后调用self.handle_stream函数处理该iostream实例

class TCPServer(object):
    def _handle_connection(self, sock, address):
        stream = IOStream(sock)                       #将与客户端连接的socket包装成iostream
         future = self.handle_stream(stream, address)  #客户端连接后不一定会立刻发来消息,处理过程也可能是异步的,所以处理连接的函数会返回一个future
         self.io_loop.add_future(future, lambda f: f.result())#将该future添加到ioloop中