协议¶
asyncio provides a set of abstract base classes that should be used
to implement network protocols. Those classes are meant to be used
together with transports.
Subclasses of abstract base protocol classes may implement some or
all methods. All these methods are callbacks: they are called by
transports on certain events, for example when some data is received.
A base protocol method should be called by the corresponding transport.
基础协议¶
classasyncio.BaseProtocol¶
Base protocol with methods that all protocols share.
classasyncio.Protocol(BaseProtocol)¶
The base class for implementing streaming protocols
(TCP, Unix sockets, etc).
classasyncio.BufferedProtocol(BaseProtocol)¶
A base class for implementing streaming protocols with manual
control of the receive buffer.
classasyncio.DatagramProtocol(BaseProtocol)¶
The base class for implementing datagram (UDP) protocols.
classasyncio.SubprocessProtocol(BaseProtocol)¶
The base class for implementing protocols communicating with child
processes (unidirectional pipes).
基础协议¶
All asyncio protocols can implement Base Protocol callbacks.
链接回调函数
Connection callbacks are called on all protocols, exactly once per
a successful connection. All other protocol callbacks can only be
called between those two methods.
BaseProtocol.connection_made(transport)¶
链接建立时被调用。
The transport argument is the transport representing the
connection. The protocol is responsible for storing the reference
to its transport.
BaseProtocol.connection_lost(exc)¶
链接丢失或关闭时被调用。
The argument is either an exception object or None.
The latter means a regular EOF is received, or the connection was
aborted or closed by this side of the connection.
流控制回调函数
Flow control callbacks can be called by transports to pause or
resume writing performed by the protocol.
See the documentation of the set_write_buffer_limits()
method for more details.
BaseProtocol.pause_writing()¶
Called when the transport's buffer goes over the high watermark.
BaseProtocol.resume_writing()¶
Called when the transport's buffer drains below the low watermark.
If the buffer size equals the high watermark,
pause_writing() is not called: the buffer size must
go strictly over.
Conversely, resume_writing() is called when the
buffer size is equal or lower than the low watermark. These end
conditions are important to ensure that things go as expected when
either mark is zero.
流协议¶
Protocol.data_received(data)¶
Called when some data is received. data is a non-empty bytes
object containing the incoming data.
Whether the data is buffered, chunked or reassembled depends on
the transport. In general, you shouldn't rely on specific semantics
and instead make your parsing generic and flexible. However,
data is always received in the correct order.
The method can be called an arbitrary number of times while
a connection is open.
However, protocol.eof_received()
is called at most once. Once eof_received() is called,
data_received() is not called anymore.
Protocol.eof_received()¶
Called when the other end signals it won't send any more data
(for example by calling transport.write_eof(), if the other end also uses
asyncio).
This method may return a false value (including None), in which case
the transport will close itself. Conversely, if this method returns a
true value, the protocol used determines whether to close the transport.
Since the default implementation returns None, it implicitly closes the
connection.
Some transports, including SSL, don't support half-closed connections,
in which case returning true from this method will result in the connection
being closed.
状态机:
start -> connection_made
[-> data_received]*
[-> eof_received]?
-> connection_lost -> end
缓冲流协议¶
3.7 新版功能:Important: this has been added to asyncio in Python 3.7
on a provisional basis! This is as an experimental API that
might be changed or removed completely in Python 3.8.
Buffered Protocols can be used with any event loop method
that supports Streaming Protocols.
BufferedProtocol implementations allow explicit manual allocation
and control of the receive buffer. Event loops can then use the buffer
provided by the protocol to avoid unnecessary data copies. This
can result in noticeable performance improvement for protocols that
receive big amounts of data. Sophisticated protocol implementations
can significantly reduce the number of buffer allocations.
The following callbacks are called on BufferedProtocol
instances:
BufferedProtocol.get_buffer(sizehint)¶
调用后会分配新的接收缓冲区。
sizehint is the recommended minimum size for the returned
buffer. It is acceptable to return smaller or larger buffers
than what sizehint suggests. When set to -1, the buffer size
can be arbitrary. It is an error to return a buffer with a zero size.
get_buffer() must return an object implementing the
buffer protocol.
BufferedProtocol.buffer_updated(nbytes)¶
用接收的数据更新缓冲区时被调用。
nbytes is the total number of bytes that were written to the buffer.
BufferedProtocol.eof_received()¶
See the documentation of the protocol.eof_received() method.
get_buffer() can be called an arbitrary number
of times during a connection. However, protocol.eof_received() is called at most once
and, if called, get_buffer() and
buffer_updated() won't be called after it.
状态机:
start -> connection_made
[-> get_buffer
[-> buffer_updated]?
]*
[-> eof_received]?
-> connection_lost -> end
数据报协议¶
Datagram Protocol instances should be constructed by protocol
factories passed to the loop.create_datagram_endpoint() method.
DatagramProtocol.datagram_received(data, addr)¶
Called when a datagram is received. data is a bytes object containing
the incoming data. addr is the address of the peer sending the data;
the exact format depends on the transport.
DatagramProtocol.error_received(exc)¶
Called when a previous send or receive operation raises an
OSError. exc is the OSError instance.
This method is called in rare conditions, when the transport (e.g. UDP)
detects that a datagram could not be delivered to its recipient.
In many conditions though, undeliverable datagrams will be silently
dropped.
注解
On BSD systems (macOS, FreeBSD, etc.) flow control is not supported
for datagram protocols, because there is no reliable way to detect send
failures caused by writing too many packets.
The socket always appears 'ready' and excess packets are dropped. An
OSError with errno set to errno.ENOBUFS may
or may not be raised; if it is raised, it will be reported to
DatagramProtocol.error_received() but otherwise ignored.
子进程协议¶
Datagram Protocol instances should be constructed by protocol
factories passed to the loop.subprocess_exec() and
loop.subprocess_shell() methods.
SubprocessProtocol.pipe_data_received(fd, data)¶
Called when the child process writes data into its stdout or stderr
pipe.
fd is the integer file descriptor of the pipe.
data is a non-empty bytes object containing the received data.
SubprocessProtocol.pipe_connection_lost(fd, exc)¶
与子进程通信的其中一个管道关闭时被调用。
fd is the integer file descriptor that was closed.
SubprocessProtocol.process_exited()¶
子进程退出时被调用。