zoukankan      html  css  js  c++  java
  • Tornado 学习笔记13 TCPServer

         为了实现TCPServer的功能,定义一个类用于继承TCPServer并实现handle_stream方法。HttpServer就是一个很好的例子。

    13.1 构造函数

    def __init__(self, io_loop=None, ssl_options=None, max_buffer_size=None,
                 read_chunk_size=None):
        self.io_loop = io_loop
        self.ssl_options = ssl_options
        self._sockets = {}  # fd -> socket object
        self._pending_sockets = []
        self._started = False
        self.max_buffer_size = max_buffer_size
        self.read_chunk_size = read_chunk_size
    
        # Verify the SSL options. Otherwise we don't get errors until clients
        # connect. This doesn't verify that the keys are legitimate, but
        # the SSL module doesn't do that until there is a connected socket
        # which seems like too much work
        if self.ssl_options is not None and isinstance(self.ssl_options, dict):
            # Only certfile is required: it can contain both keys
            if 'certfile' not in self.ssl_options:
                raise KeyError('missing key "certfile" in ssl_options')
    
            if not os.path.exists(self.ssl_options['certfile']):
                raise ValueError('certfile "%s" does not exist' %
                                 self.ssl_options['certfile'])
            if ('keyfile' in self.ssl_options and
                    not os.path.exists(self.ssl_options['keyfile'])):
                raise ValueError('keyfile "%s" does not exist' %
                                 self.ssl_options['keyfile'])

         实现流程如下:

    (1) 设置属性。

    (2) 判断是否支持SLL,如果支持,判断证书文件以及秘钥文件是否存在。

    13.2 监听 listen

              开启指定端口的接收连接。

              为了监听多个端口时,这个方法可能会被调用多次。这个方法会立即起作用,不需要调用TCPServer.start方法。但是,还是有必要启动IOLoop。

    def listen(self, port, address=""):
        """Starts accepting connections on the given port.
    
        This method may be called more than once to listen on multiple ports.
        `listen` takes effect immediately; it is not necessary to call
        `TCPServer.start` afterwards.  It is, however, necessary to start
        the `.IOLoop`.
        """
        sockets = bind_sockets(port, address=address)
        self.add_sockets(sockets)

              调用bind_sockets方法来获得sockets集合对象。调用add_sockets方法循环处理每一个sockets对象,主要注册socket建立连接后的处理回调函数。

    13.3 添加sockets (add_sockets)


    def add_sockets(self, sockets):
        """Makes this server start accepting connections on the given sockets.
    
        The ``sockets`` parameter is a list of socket objects such as
        those returned by `~tornado.netutil.bind_sockets`.
        `add_sockets` is typically used in combination with that
        method and `tornado.process.fork_processes` to provide greater
        control over the initialization of a multi-process server.
        """
        if self.io_loop is None:
            self.io_loop = IOLoop.current()
    
        for sock in sockets:
            self._sockets[sock.fileno()] = sock
            add_accept_handler(sock, self._handle_connection,
                               io_loop=self.io_loop)

             针对每一个socket, 注册socket建立连接后的处理回调函数,回调函数为内部方法_handle_connection。

    13.4 关闭服务器(stop)

    def stop(self):
        """Stops listening for new connections.
    
        Requests currently in progress may still continue after the
        server is stopped.
        """
        for fd, sock in self._sockets.items():
            self.io_loop.remove_handler(fd)
            sock.close()

             关闭服务器,停止监新的请求连接。在服务器关闭之后,当前正在处理的请求会继续执行。

            执行逻辑就是,对服务器中所有的sockets对象,调用两个方法,一个是移除io_loop中的处理回调函数,一个是关闭socket.

    13.5 socket的建立连接后的回调函数 _handle_connection

               socket处理请求时,这个方法是回调函数,用来处理请求流。如果请求是SSL请求,则初始化SSLIOStream类,如果不是SSL请求,则初始化IOStream类。初始化Stream之后,调用handle_stream方法来处理stream.handler_stream方法一般由TCPServer的子类实现,比如HttpServer就有具体的实现。
  • 相关阅读:
    【转载】使用缓存的9个误区(上)
    .NET开发者必备的工具箱(转载)
    Java基础之反射(一)
    【干货转载】.NET中的六个重要概念:栈、堆、值类型、引用类型、装箱和拆箱
    CKEditor配置详解
    ASP.NET中IsPostBack的理解
    三层架构与设计模式思想部署企业级数据库业务系统开发
    AppDomain 详解(转)
    字符串基础总结
    访问数据库的时候报错 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
  • 原文地址:https://www.cnblogs.com/liaofeifight/p/5086393.html
Copyright © 2011-2022 走看看