傳輸與協定

前言

Transports and Protocols are used by the low-level event loop APIs such as loop.create_connection(). They use callback-based programming style and enable high-performance implementations of network or IPC protocols (e.g. HTTP).

Essentially, transports and protocols should only be used in libraries and frameworks and never in high-level asyncio applications.

This documentation page covers both Transports and Protocols.

Introduction

At the highest level, the transport is concerned with how bytes are transmitted, while the protocol determines which bytes to transmit (and to some extent when).

A different way of saying the same thing: a transport is an abstraction for a socket (or similar I/O endpoint) while a protocol is an abstraction for an application, from the transport's point of view.

Yet another view is the transport and protocol interfaces together define an abstract interface for using network I/O and interprocess I/O.

There is always a 1:1 relationship between transport and protocol objects: the protocol calls transport methods to send data, while the transport calls protocol methods to pass it data that has been received.

Most of connection oriented event loop methods (such as loop.create_connection()) usually accept a protocol_factory argument used to create a Protocol object for an accepted connection, represented by a Transport object. Such methods usually return a tuple of (transport, protocol).

目錄

This documentation page contains the following sections:

Transports

原始碼:Lib/asyncio/transports.py


Transports are classes provided by asyncio in order to abstract various kinds of communication channels.

Transport objects are always instantiated by an asyncio event loop.

asyncio implements transports for TCP, UDP, SSL, and subprocess pipes. The methods available on a transport depend on the transport's kind.

The transport classes are not thread safe.

Transports Hierarchy

class asyncio.BaseTransport

Base class for all transports. Contains methods that all asyncio transports share.

class asyncio.WriteTransport(BaseTransport)

A base transport for write-only connections.

Instances of the WriteTransport class are returned from the loop.connect_write_pipe() event loop method and are also used by subprocess-related methods like loop.subprocess_exec().

class asyncio.ReadTransport(BaseTransport)

A base transport for read-only connections.

Instances of the ReadTransport class are returned from the loop.connect_read_pipe() event loop method and are also used by subprocess-related methods like loop.subprocess_exec().

class asyncio.Transport(WriteTransport, ReadTransport)

Interface representing a bidirectional transport, such as a TCP connection.

The user does not instantiate a transport directly; they call a utility function, passing it a protocol factory and other information necessary to create the transport and protocol.

Instances of the Transport class are returned from or used by event loop methods like loop.create_connection(), loop.create_unix_connection(), loop.create_server(), loop.sendfile(), etc.

class asyncio.DatagramTransport(BaseTransport)

A transport for datagram (UDP) connections.

Instances of the DatagramTransport class are returned from the loop.create_datagram_endpoint() event loop method.

class asyncio.SubprocessTransport(BaseTransport)

An abstraction to represent a connection between a parent and its child OS process.

Instances of the SubprocessTransport class are returned from event loop methods loop.subprocess_shell() and loop.subprocess_exec().

Base Transport

BaseTransport.close()

Close the transport.

If the transport has a buffer for outgoing data, buffered data will be flushed asynchronously. No more data will be received. After all buffered data is flushed, the protocol's protocol.connection_lost() method will be called with None as its argument. The transport should not be used once it is closed.

BaseTransport.is_closing()

Return True if the transport is closing or is closed.

BaseTransport.get_extra_info(name, default=None)

Return information about the transport or underlying resources it uses.

name is a string representing the piece of transport-specific information to get.

default is the value to return if the information is not available, or if the transport does not support querying it with the given third-party event loop implementation or on the current platform.

For example, the following code attempts to get the underlying socket object of the transport:

sock = transport.get_extra_info('socket')
if sock is not None:
    print(sock.getsockopt(...))

Categories of information that can be queried on some transports:

BaseTransport.set_protocol(protocol)

Set a new protocol.

Switching protocol should only be done when both protocols are documented to support the switch.

BaseTransport.get_protocol()

Return the current protocol.

Read-only Transports

ReadTransport.is_reading()

Return True if the transport is receiving new data.

在 3.7 版被加入.

ReadTransport.pause_reading()

Pause the receiving end of the transport. No data will be passed to the protocol's protocol.data_received() method until resume_reading() is called.

在 3.7 版的變更: The method is idempotent, i.e. it can be called when the transport is already paused or closed.

ReadTransport.resume_reading()

Resume the receiving end. The protocol's protocol.data_received() method will be called once again if some data is available for reading.

在 3.7 版的變更: The method is idempotent, i.e. it can be called when the transport is already reading.

Write-only Transports

WriteTransport.abort()

Close the transport immediately, without waiting for pending operations to complete. Buffered data will be lost. No more data will be received. The protocol's protocol.connection_lost() method will eventually be called with None as its argument.

WriteTransport.can_write_eof()

Return True if the transport supports write_eof(), False if not.

WriteTransport.get_write_buffer_size()

Return the current size of the output buffer used by the transport.

WriteTransport.get_write_buffer_limits()

Get the high and low watermarks for write flow control. Return a tuple (low, high) where low and high are positive number of bytes.

Use set_write_buffer_limits() to set the limits.

在 3.4.2 版被加入.

WriteTransport.set_write_buffer_limits(high=None, low=None)

Set the high and low watermarks for write flow control.

These two values (measured in number of bytes) control when the protocol's protocol.pause_writing() and protocol.resume_writing() methods are called. If specified, the low watermark must be less than or equal to the high watermark. Neither high nor low can be negative.

pause_writing() is called when the buffer size becomes greater than or equal to the high value. If writing has been paused, resume_writing() is called when the buffer size becomes less than or equal to the low value.

The defaults are implementation-specific. If only the high watermark is given, the low watermark defaults to an implementation-specific value less than or equal to the high watermark. Setting high to zero forces low to zero as well, and causes pause_writing() to be called whenever the buffer becomes non-empty. Setting low to zero causes resume_writing() to be called only once the buffer is empty. Use of zero for either limit is generally sub-optimal as it reduces opportunities for doing I/O and computation concurrently.

Use get_write_buffer_limits() to get the limits.

WriteTransport.write(data)

Write some data bytes to the transport.

This method does not block; it buffers the data and arranges for it to be sent out asynchronously.

WriteTransport.