tornado.iostream — 非阻塞套接字的便捷包装器

用于写入和读取非阻塞文件和套接字的实用程序类。

内容

基类

class tornado.iostream.BaseIOStream(max_buffer_size: Optional[int] = None, read_chunk_size: Optional[int] = None, max_write_buffer_size: Optional[int] = None)[source]

用于写入和读取非阻塞文件或套接字的实用程序类。

我们支持非阻塞的 write() 和一系列 read_*() 方法。当操作完成时,Awaitable 将解析为读取的数据(对于 write() 则为 None)。当流关闭时,所有未完成的 Awaitables 将解析为 StreamClosedErrorBaseIOStream.set_close_callback 也可以用来通知流关闭。

当流因错误而关闭时,IOStream 的 error 属性将包含异常对象。

子类必须实现 filenoclose_fdwrite_to_fdread_from_fd,并可选地实现 get_fd_error

BaseIOStream 构造函数。

参数
  • max_buffer_size – 缓冲传入数据的最大量;默认为 100MB。

  • read_chunk_size – 从底层传输中一次读取的数据量;默认为 64KB。

  • max_write_buffer_size – 缓冲传出数据的量;默认为无限制。

在版本 4.0 中更改: 添加了 max_write_buffer_size 参数。将默认的 read_chunk_size 更改为 64KB。

在版本 5.0 中更改: 已删除 io_loop 参数(自版本 4.1 起已弃用)。

主接口

BaseIOStream.write(data: Union[bytes, memoryview]) Future[None][source]

异步地将给定数据写入此流。

此方法返回一个 Future,当写入完成时,该 Future 将解析(结果为 None)。

data 参数可以是 bytesmemoryview 类型。

在版本 4.0 中更改: 现在,如果未给出回调,则返回一个 Future

在版本 4.5 中更改: 添加了对 memoryview 参数的支持。

在版本 6.0 中更改: 已删除 callback 参数。请改用返回的 Future

BaseIOStream.read_bytes(num_bytes: int, partial: bool = False) Awaitable[bytes][source]

异步地读取一定数量的字节。

如果 partial 为 true,则只要我们有字节要返回就返回数据(但绝不会超过 num_bytes)。

在版本 4.0 中更改: 添加了 partial 参数。回调参数现在是可选的,如果省略了它,则将返回一个 Future

在版本 6.0 中更改: 已删除 callbackstreaming_callback 参数。请改用返回的 Future(对于 streaming_callback 则使用 partial=True)。

BaseIOStream.read_into(buf: bytearray, partial: bool = False) Awaitable[int][source]

异步地读取一定数量的字节。

buf 必须是一个可写的缓冲区,数据将被读入其中。

如果 partial 为真,则一旦读取到任何字节,回调就会运行。否则,当 buf 已完全填充读取数据时运行。

版本 5.0 中的新增功能。

在版本 6.0 中更改: 已删除 callback 参数。请改用返回的 Future

BaseIOStream.read_until(delimiter: bytes, max_bytes: Optional[int] = None) Awaitable[bytes][source]

异步读取直到找到给定的分隔符。

结果包括所有读取的数据,包括分隔符。

如果 max_bytes 不为 None,则如果读取了超过 max_bytes 字节并且未找到分隔符,连接将被关闭。

版本 4.0 中的更改: 添加了 max_bytes 参数。 callback 参数现在是可选的,如果省略,将返回一个 Future

在版本 6.0 中更改: 已删除 callback 参数。请改用返回的 Future

BaseIOStream.read_until_regex(regex: bytes, max_bytes: Optional[int] = None) Awaitable[bytes][source]

异步读取直到匹配给定的正则表达式。

结果包括匹配正则表达式的部分和它前面的所有数据。

如果 max_bytes 不为 None,则如果读取了超过 max_bytes 字节并且正则表达式未得到满足,连接将被关闭。

版本 4.0 中的更改: 添加了 max_bytes 参数。 callback 参数现在是可选的,如果省略,将返回一个 Future

在版本 6.0 中更改: 已删除 callback 参数。请改用返回的 Future

BaseIOStream.read_until_close() Awaitable[bytes][source]

异步读取套接字中的所有数据,直到它关闭。

这将缓冲所有可用数据,直到达到 max_buffer_size。如果需要流控制或取消,请使用带有 read_bytes(partial=True) 的循环。

版本 4.0 中的更改: callback 参数现在是可选的,如果省略,将返回一个 Future

版本 6.0 中的更改: 已删除 callbackstreaming_callback 参数。请使用返回的 Future(以及带有 partial=Trueread_bytes 用于 streaming_callback)代替。

BaseIOStream.close(exc_info: Union[None, bool, BaseException, Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]]] = False) None[source]

关闭此流。

如果 exc_info 为真,则将 error 属性设置为 sys.exc_info 中的当前异常(或者如果 exc_info 是一个元组,则使用它而不是 sys.exc_info)。

BaseIOStream.set_close_callback(callback: Optional[Callable[[], None]]) None[source]

当流关闭时调用给定的回调。

对于使用 Future 接口的应用程序,这通常是不必要的;当流关闭时,所有未完成的 Futures 将以 StreamClosedError 方式解析。但是,它仍然可以用作在没有其他读写操作正在进行的情况下,发出流已关闭信号的一种方式。

与其他基于回调的接口不同,set_close_callback 在 Tornado 6.0 中没有被移除。

BaseIOStream.closed() bool[source]

如果流已关闭,则返回 True

BaseIOStream.reading() bool[source]

如果我们当前正在从流中读取数据,则返回 True

BaseIOStream.writing() bool[source]

如果我们当前正在向流中写入数据,则返回 True

BaseIOStream.set_nodelay(value: bool) None[source]

设置此流的无延迟标志。

默认情况下,写入 TCP 流的数据可能会被保留一段时间,以最大限度地利用带宽(根据 Nagle 算法)。无延迟标志请求尽快写入数据,即使这样做会消耗更多带宽。

此标志目前仅针对基于 TCP 的 IOStreams 定义。

新版本 3.1 中添加。

子类方法

BaseIOStream.fileno() Union[int, _Selectable][source]

返回此流的文件描述符。

BaseIOStream.close_fd() None[source]

关闭此流底层的文件。

close_fdBaseIOStream 调用,不应在其他地方调用;其他用户应调用 close

BaseIOStream.write_to_fd(data: memoryview) int[source]

尝试将 data 写入底层文件。

返回写入的字节数。

BaseIOStream.read_from_fd(buf: Union[bytearray, memoryview]) Optional[int][source]

尝试从底层文件读取。

读取最多 len(buf) 字节,并将它们存储在缓冲区中。返回读取的字节数。如果没有任何内容可读(套接字返回 EWOULDBLOCK 或等效值),则返回 None,在 EOF 时返回 0。

版本 5.0 中更改: 接口重新设计为接受一个缓冲区并返回字节数而不是一个新分配的对象。

BaseIOStream.get_fd_error() Optional[Exception][source]

返回有关底层文件上任何错误的信息。

此方法是在 IOLoop 信号文件描述符上的错误后调用的,应返回一个异常(例如 socket.error,其中包含其他信息,或者如果无可用信息,则返回 None。

实现

class tornado.iostream.IOStream(socket: socket, *args: Any, **kwargs: Any)[source]

基于套接字的 IOStream 实现。

此类支持来自 BaseIOStream 的读写方法以及一个 connect 方法。

socket 参数可以是已连接的,也可以是未连接的。对于服务器操作,套接字是调用 socket.accept 的结果。对于客户端操作,套接字是用 socket.socket 创建的,可以先连接再传递给 IOStream,也可以用 IOStream.connect 连接。

使用此类实现的非常简单(并且有问题的)HTTP 客户端

import socket
import tornado

async def main():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
    stream = tornado.iostream.IOStream(s)
    await stream.connect(("friendfeed.com", 80))
    await stream.write(b"GET / HTTP/1.0\r\nHost: friendfeed.com\r\n\r\n")
    header_data = await stream.read_until(b"\r\n\r\n")
    headers = {}
    for line in header_data.split(b"\r\n"):
        parts = line.split(b":")
        if len(parts) == 2:
            headers[parts[0].strip()] = parts[1].strip()
    body_data = await stream.read_bytes(int(headers[b"Content-Length"]))
    print(body_data)
    stream.close()

if __name__ == '__main__':
    asyncio.run(main())
connect(address: Any, server_hostname: Optional[str] = None) Future[_IOStreamType][source]

在不阻塞的情况下将套接字连接到远程地址。

仅当构造函数传递的套接字之前没有连接时才能调用此方法。地址参数与为 socket.connect 传递给 IOStream 构造函数的套接字类型相同的格式,例如 (ip, port) 元组。此处接受主机名,但将同步解析并阻塞 IOLoop。如果您有主机名而不是 IP 地址,则建议使用 TCPClient 类,而不是直接调用此方法。 TCPClient 将执行异步 DNS 解析并处理 IPv4 和 IPv6。

如果指定了 callback,它将在连接完成时被调用,不带参数;如果未指定,此方法将返回一个 Future(在成功连接后其结果将是流本身)。

在 SSL 模式下,server_hostname 参数将用于证书验证(除非在 ssl_options 中禁用)和 SNI(如果支持;需要 Python 2.7.9+)。

请注意,在连接挂起时调用 IOStream.write 是安全的,在这种情况下,数据将在连接就绪后立即写入。在套接字连接之前调用 IOStream 读取方法在某些平台上有效,但不可移植。

版本 4.0 中的变更: 如果未给出回调,则返回一个 Future

版本 4.2 中的变更: 默认情况下会验证 SSL 证书;传递 ssl_options=dict(cert_reqs=ssl.CERT_NONE) 或一个适当配置的 ssl.SSLContextSSLIOStream 构造函数以禁用。

在版本 6.0 中更改: 已删除 callback 参数。请改用返回的 Future

start_tls(server_side: bool, ssl_options: Optional[Union[Dict[str, Any], SSLContext]] = None, server_hostname: Optional[str] = None) Awaitable[SSLIOStream][source]

将此 IOStream 转换为 SSLIOStream

这使能够使用在明文模式下开始并在一些初始协商后切换到 SSL 的协议(例如 STARTTLS 对 SMTP 和 IMAP 的扩展)。

如果流上有未完成的读取或写入,或者 IOStream 的缓冲区中有任何数据(操作系统套接字缓冲区中的数据是允许的),则此方法不可用。这意味着它通常必须在读取或写入最后一个明文数据后立即使用。它也可以在连接后立即使用,在任何读取或写入之前。

ssl_options 参数可以是 ssl.SSLContext 对象,也可以是 ssl.SSLContext.wrap_socket 函数的关键字参数字典。除非在 ssl_options 中禁用,否则 server_hostname 参数将用于证书验证。

此方法返回一个 Future,其结果是新的 SSLIOStream。在调用此方法后,对原始流的任何其他操作都是未定义的。

如果在此流上定义了关闭回调,它将被转移到新流。

版本 4.0 中的新增功能。

版本 4.2 中的变更: 默认情况下会验证 SSL 证书;传递 ssl_options=dict(cert_reqs=ssl.CERT_NONE) 或一个适当配置的 ssl.SSLContext 以禁用。

class tornado.iostream.SSLIOStream(*args: Any, **kwargs: Any)[source]

一个用于写入和读取非阻塞 SSL 套接字的实用程序类。

如果传递给构造函数的套接字已连接,则应将其包装为

ssl.SSLContext(...).wrap_socket(sock, do_handshake_on_connect=False, **kwargs)

在构造 SSLIOStream 之前。未连接的套接字将在 IOStream.connect 完成后被包装。

ssl_options 关键字参数可以是 ssl.SSLContext 对象,也可以是 ssl.SSLContext.wrap_socket 的关键字参数字典。

wait_for_handshake() Future[SSLIOStream][source]

等待初始 SSL 握手完成。

如果给出了 callback,则握手完成后将不带参数调用它;否则,此方法将返回一个 Future,该对象在握手完成后将解析为流本身。

握手完成后,可以在 self.socket 上访问诸如对等方证书和 NPN/ALPN 选择等信息。

此方法旨在用于服务器端流或在使用 IOStream.start_tls 之后;它不应该与 IOStream.connect 一起使用(该方法已经等待握手完成)。它每个流只能调用一次。

版本 4.2 中的新增功能。

在版本 6.0 中更改: 已删除 callback 参数。请改用返回的 Future

class tornado.iostream.PipeIOStream(fd: int, *args: Any, **kwargs: Any)[source]

基于管道的 IOStream 实现。

构造函数接受一个整数文件描述符(例如由 os.pipe 返回的),而不是一个打开的文件对象。管道通常是单向的,因此 PipeIOStream 可用于读或写,但不能同时用于两者。

PipeIOStream 仅在基于 Unix 的平台上可用。

异常

exception tornado.iostream.StreamBufferFullError[source]

当缓冲区已满时,由 IOStream 方法引发的异常。

exception tornado.iostream.StreamClosedError(real_error: Optional[BaseException] = None)[source]

当流关闭时,由 IOStream 方法引发的异常。

请注意,关闭回调是在流上的其他回调之后计划执行的(以允许处理缓冲数据),因此您可能会在看到关闭回调之前看到此错误。

real_error 属性包含导致流关闭的底层错误(如果有)。

版本 4.3 中的更改: 添加了 real_error 属性。

exception tornado.iostream.UnsatisfiableReadError[source]

当无法满足读取操作时引发的异常。

read_untilread_until_regex 以及 max_bytes 参数引发。