tornado.tcpserver — Basic IOStream-based TCP server

非阻塞单线程TCP服务器.

class tornado.tcpserver.TCPServer(ssl_options: Union[Dict[str, Any], ssl.SSLContext] = None, max_buffer_size: int = None, read_chunk_size: int = None)[source]

非阻塞单线程TCP服务器.

要使用TCPServer ,请定义一个覆盖handle_stream方法的子类. 例如,可以这样定义一个简单的回显服务器:

from tornado.tcpserver import TCPServer
from tornado.iostream import StreamClosedError
from tornado import gen

class EchoServer(TCPServer):
    async def handle_stream(self, stream, address):
        while True:
            try:
                data = await stream.read_until(b"\n")
                await stream.write(data)
            except StreamClosedError:
                break

要使该服务器提供SSL流量,请发送带有ssl.SSLContext对象的ssl_options关键字参数. 为了与旧版本的Python兼容, ssl_options也可以是ssl.wrap_socket方法的关键字参数字典:

ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
ssl_ctx.load_cert_chain(os.path.join(data_dir, "mydomain.crt"),
                        os.path.join(data_dir, "mydomain.key"))
TCPServer(ssl_options=ssl_ctx)

TCPServer初始化遵循以下三种模式之一:

  1. listen :简单的单进程:

    server = TCPServer()
    server.listen(8888)
    IOLoop.current().start()
    
  2. bind / start :简单的多进程:

    server = TCPServer()
    server.bind(8888)
    server.start(0)  # Forks multiple sub-processes
    IOLoop.current().start()
    

    使用此接口时, 不得IOLoop传递给TCPServer构造函数. start将始终在默认的单例IOLoop上启动服务器.

  3. add_sockets :高级多进程:

    sockets = bind_sockets(8888)
    tornado.process.fork_processes(0)
    server = TCPServer()
    server.add_sockets(sockets)
    IOLoop.current().start()
    

    add_sockets接口较为复杂,但可以与tornado.process.fork_processes结合使用,以在发生分叉时提供更大的灵活性. 如果您想以除bind_sockets其他方式创建监听套接字,则add_sockets也可以在单进程服务器中使用.

3.1版的新功能: The max_buffer_size argument.

在版本5.0中更改: io_loop参数已删除.

listen(port: int, address: str = '') → None[source]

开始接受给定端口上的连接.

可以多次调用此方法以侦听多个端口. listen立即生效; 之后不必调用TCPServer.start . 但是,有必要启动IOLoop .

add_sockets(sockets: Iterable[socket.socket]) → None[source]

使该服务器开始接受给定套接字上的连接.

sockets参数是套接字对象的列表,例如bind_sockets返回的bind_sockets . add_sockets通常与该方法和tornado.process.fork_processes结合使用,以更好地控制多进程服务器的初始化.

add_socket(socket: socket.socket) → None[source]

add_sockets单数版本. 接受一个套接字对象.

bind(port: int, address: str = None, family: socket.AddressFamily = <AddressFamily.AF_UNSPEC: 0>, backlog: int = 128, reuse_port: bool = False) → None[source]

将此服务器绑定到给定地址上的给定端口.

要启动服务器,请调用start . 如果要在单个进程中运行此服务器,则可以调用listen作为bindstart调用序列的快捷方式.

地址可以是IP地址或主机名. 如果是主机名,则服务器将侦听与该名称关联的所有IP地址. 地址可以是空字符串,也可以是"无"以侦听所有可用接口. 可以将Family设置为socket.AF_INETsocket.AF_INET6以限制为IPv4或IPv6地址,否则将同时使用这两个地址(如果可用).

backlog参数的含义与socket.listen含义相同. reuse_port参数的含义与bind_sockets含义相同.

start侦听多个端口或接口之前,可以多次调用此方法.

在版本4.4中进行了更改:添加了reuse_port参数.

start(num_processes: Optional[int] = 1, max_restarts: int = None) → None[source]

IOLoop启动此服务器.

默认情况下,我们在此过程中运行服务器,并且不会派生任何其他子进程.

如果num_processes为None或<= 0,我们将检测此计算机上可用的内核数,并派生该数量的子进程. 如果给定num_processes且> 1,则我们分叉该特定数量的子进程.

由于我们使用进程而不是线程,因此任何服务器代码之间都没有共享内存.

请注意,多个进程与autoreload模块不兼容(或tornado.web.Applicationautoreload=True选项,当debug=True时默认为debug=True ). 使用多个进程时,直到调用TCPServer.start(n)之后,才能创建或引用IOLoop.

max_restarts参数传递给fork_processes .

在版本6.0中更改: Added max_restarts argument.

stop() → None[source]

Stops listening for new connections.

服务器停止后,当前正在进行的请求可能仍会继续.

handle_stream(stream: tornado.iostream.IOStream, address: tuple) → Optional[Awaitable[None]][source]

重写以处理来自传入连接的新IOStream .

这种方法可能是协程; 如果是这样,它将以异步方式引发任何异常. 该协程不会阻止接受传入的连接.

如果此TCPServer配置为使用SSL,则可以在SSL握手完成之前调用handle_stream . 如果需要验证客户端的证书或使用NPN / ALPN,请使用SSLIOStream.wait_for_handshake .

在版本4.2中进行了更改: Added the option for this method to be a coroutine.