Skip to main content

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

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

内容:

基类

class tornado.iostream.BaseIOStream(io_loop=None, max_buffer_size=None, read_chunk_size=None, max_write_buffer_size=None)[源代码]

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

我们支持非阻塞 write() 和一系列 read_*() 方法。所有的方法都有一个可选的 callback 参数,并且只有在没有回调的情况下才返回一个 Future。当操作完成时,将运行回调或 Future 将解析读取的数据(或 write()None)。当流关闭时,所有未完成的 Futures 将用 StreamClosedError 解析;回调接口的用户将通过 BaseIOStream.set_close_callback 通知。

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

子类必须实现 filenoclose_fdwrite_to_fdread_from_fd 和可选的 get_fd_error

BaseIOStream 构造函数。

参数:
  • io_loopIOLoop 使用;默认为 IOLoop.current。自从Tornado 4.1以来已弃用。
  • max_buffer_size – 进入缓冲区的最大数据量;默认为100MB。
  • read_chunk_size – 从底层传输一次读取的数据量;默认为64KB。
  • max_write_buffer_size – 输出到缓冲区的数据量;默认为unlimited。

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

主界面

BaseIOStream.write(data, callback=None)[源代码]

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

如果给出了 callback,当所有缓冲的写数据已成功写入流时,我们称之为 callback。如果存在先前缓冲的写入数据和旧的写回调,则该回调被这个新的回调简单地覆盖。

如果没有给出 callback,则该方法返回一个 Future,该值在写入完成时解析(使用 None 的结果)。如果在 Future 解决之前再次调用 write,则以前的将来将被孤立,并且永远不会解析。

在 4.0 版更改: 现在返回 Future 如果没有回调。

BaseIOStream.read_bytes(num_bytes, callback=None, streaming_callback=None, partial=False)[源代码]

异步读取多个字节。

如果给出了 streaming_callback,它将在数据块变得可用时被调用,并且最终结果将为空。否则,结果是读取的所有数据。如果给出回调,它将以数据作为参数运行;如果不是,此方法返回 Future

如果 partial 为真,回调函数一旦我们有任何字节要返回(但永远不会超过 num_bytes

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

BaseIOStream.read_until(delimiter, callback=None, max_bytes=None)[源代码]

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

结果包括读取的所有数据,包括分隔符。如果给出回调,它将以数据作为参数运行;如果不是,此方法返回 Future

如果 max_bytes 不是无,如果读取的字节超过 max_bytes,并且找不到分隔符,则连接将关闭。

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

BaseIOStream.read_until_regex(regex, callback=None, max_bytes=None)[源代码]

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

结果包括匹配正则表达式以及其前面的任何内容的数据。如果给出回调,它将以数据作为参数运行;如果不是,此方法返回 Future

如果 max_bytes 不是无,如果超过 max_bytes 字节已被读取并且不满足正则表达式,则连接将被关闭。

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

BaseIOStream.read_until_close(callback=None, streaming_callback=None)[源代码]

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

如果给出了 streaming_callback,它将在数据块变得可用时被调用,并且最终结果将为空。否则,结果是读取的所有数据。如果给出回调,它将以数据作为参数运行;如果不是,此方法返回 Future

注意,如果使用 streaming_callback,将从套接字中读取数据,直到它可用;没有办法应用背压或取消读数。如果需要流量控制或取消,请使用带 read_bytes(partial=True) 的回路。

在 4.0 版更改: 回调参数现在是可选的,如果省略,将返回 Future

BaseIOStream.close(exc_info=False)[源代码]

关闭此流。

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

BaseIOStream.set_close_callback(callback)[源代码]

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

这对于使用 Future 接口的应用程序不是必需的;所有未决的 Futures 将在流关闭时使用 StreamClosedError 解析。

BaseIOStream.closed()[源代码]

如果流已关闭,则返回true。

BaseIOStream.reading()[源代码]

如果我们正在从流读取,则返回true。

BaseIOStream.writing()[源代码]

如果我们正在写入流,则返回true。

BaseIOStream.set_nodelay(value)[源代码]

设置此流的无延迟标志。

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

此标志当前仅为基于TCP的 IOStreams 定义。

3.1 新版功能.

子类的方法

BaseIOStream.fileno()[源代码]

返回此流的文件描述符。

BaseIOStream.close_fd()[源代码]

关闭此流下面的文件。

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

BaseIOStream.write_to_fd(data)[源代码]

尝试将 data 写入基础文件。

返回写入的字节数。

BaseIOStream.read_from_fd()[源代码]

尝试从底层文件读取。

如果没有什么要读取,则返回 None (套接字返回 EWOULDBLOCK 或等效值),否则返回数据。如果可能,应一次返回不超过 self.read_chunk_size 字节。

BaseIOStream.get_fd_error()[源代码]

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

此方法在 IOLoop 在文件描述符上发出错误信号后调用,并应返回异常(如带有附加信息的 socket.error,如果没有此类信息,则返回None)。

实现

class tornado.iostream.IOStream(socket, *args, **kwargs)[源代码]

基于套接字的 IOStream 实现。

该类支持 BaseIOStream 的读写方法和 connect 方法。

socket 参数可以连接或不连接。对于服务器操作,套接字是调用 socket.accept 的结果。对于客户端操作,使用 socket.socket 创建套接字,并且可以在将套接字传递给 IOStream 或连接到 IOStream.connect 之前进行连接。

使用此类的一个非常简单(和破碎)的HTTP客户端:

import tornado.ioloop
import tornado.iostream
import socket

def send_request():
    stream.write(b"GET / HTTP/1.0\r\nHost: friendfeed.com\r\n\r\n")
    stream.read_until(b"\r\n\r\n", on_headers)

def on_headers(data):
    headers = {}
    for line in data.split(b"\r\n"):
       parts = line.split(b":")
       if len(parts) == 2:
           headers[parts[0].strip()] = parts[1].strip()
    stream.read_bytes(int(headers[b"Content-Length"]), on_body)

def on_body(data):
    print(data)
    stream.close()
    tornado.ioloop.IOLoop.current().stop()

if __name__ == '__main__':
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
    stream = tornado.iostream.IOStream(s)
    stream.connect(("friendfeed.com", 80), send_request)
    tornado.ioloop.IOLoop.current().start()
connect(address, callback=None, server_hostname=None)[源代码]

将套接字连接到远程地址而不阻塞。

仅当传递给构造函数的套接字以前未连接时才可以调用。地址参数与传送给IOStream构造函数的套接字类型的 socket.connect 格式相同。 (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.SSLContext 传递给 SSLIOStream 构造函数以禁用。

start_tls(server_side, ssl_options=None, server_hostname=None)[源代码]

将此 IOStream 转换为 SSLIOStream

这将启用以纯文本模式开始并在进行一些初始协商(例如对SMTP和IMAP的 STARTTLS 扩展)后切换到SSL的协议。

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

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

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

如果在此流上定义了close回调,它将被传输到新流。

4.0 新版功能.

在 4.2 版更改: SSL证书默认验证;通过 ssl_options=dict(cert_reqs=ssl.CERT_NONE) 或适当配置的 ssl.SSLContext 以禁用。

class tornado.iostream.SSLIOStream(*args, **kwargs)[源代码]

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

如果传递给构造函数的套接字已经连接,它应该被包装:

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

在构建 SSLIOStream 之前。当 IOStream.connect 完成时,未连接的套接字将被包装。

ssl_options 关键字参数可以是 ssl.wrap_socketssl.SSLContext 对象或关键字参数的字典

wait_for_handshake(callback=None)[源代码]

等待初始SSL握手完成。

如果给出 callback,一旦握手完成,将无参数地调用它;否则此方法返回一个 Future,它将在握手完成后解析到流本身。

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

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

4.2 新版功能.

class tornado.iostream.PipeIOStream(fd, *args, **kwargs)[源代码]

基于管道的 IOStream 实现。

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

例外

exception tornado.iostream.StreamBufferFullError[源代码]

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

exception tornado.iostream.StreamClosedError(real_error=None)[源代码]

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

请注意,close回调被安排在流上运行 after 其他回调(以允许处理缓冲的数据),因此您可能在看到close回调之前看到此错误。

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

在 4.3 版更改: 添加了 real_error 属性。

exception tornado.iostream.UnsatisfiableReadError[源代码]

无法满足读取时出现异常。

read_untilread_until_regex 通过 max_bytes 参数引发。