“Python/docs/3.9/library/asyncio-protocol”的版本间差异

来自菜鸟教程
Python/docs/3.9/library/asyncio-protocol
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:传输和协议 — Python 文档}}
 
<div id="transports-and-protocols" class="section">
 
<div id="transports-and-protocols" class="section">
  
 
<span id="asyncio-transports-protocols"></span>
 
<span id="asyncio-transports-protocols"></span>
= Transports and Protocols =
+
= 传输和协议 =
  
Preface
+
前言
  
Transports and Protocols are used by the '''low-level''' event loop
+
传输和协议由 '''低级''' 事件循环 API 使用,例如 <code>loop.create_connection()</code>。 它们使用基于回调的编程风格并支持网络或 IPC 协议的高性能实现(例如 HTTP)。
APIs such as [[../asyncio-eventloop#asyncio.loop|<code>loop.create_connection()</code>]]. 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|Transports]] and [[#protocols|Protocols]].
+
本文档页面涵盖 [[#transports|传输]] [[#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
+
说同一件事的另一种方式:从传输的角度来看,传输是套接字(或类似的 I/O 端点)的抽象,而协议是应用程序的抽象。
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
+
另一个观点是传输接口和协议接口一起定义了一个抽象接口,用于使用网络 I/O 和进程间 I/O。
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
+
传输和协议对象之间始终存在 1:1 的关系:协议调用传输方法发送数据,而传输调用协议方法将接收到的数据传递给它。
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
+
大多数面向连接的事件循环方法(例如 <code>loop.create_connection()</code>)通常接受一个 ''protocol_factory'' 参数,用于为已接受的连接创建 ''Protocol'' 对象,由 ''表示]传输''对象。 此类方法通常返回 <code>(transport, protocol)</code> 的元组。
(such as [[../asyncio-eventloop#asyncio.loop|<code>loop.create_connection()</code>]]) 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 <code>(transport, protocol)</code>.
 
  
Contents
+
内容
  
This documentation page contains the following sections:
+
此文档页面包含以下部分:
  
* The [[#transports|Transports]] section documents asyncio [[#asyncio.BaseTransport|<code>BaseTransport</code>]], [[#asyncio.ReadTransport|<code>ReadTransport</code>]], [[#asyncio.WriteTransport|<code>WriteTransport</code>]], [[#asyncio.Transport|<code>Transport</code>]], [[#asyncio.DatagramTransport|<code>DatagramTransport</code>]], and [[#asyncio.SubprocessTransport|<code>SubprocessTransport</code>]] classes.
+
* [[#transports|Transports]] 部分记录了 asyncio [[#asyncio.BaseTransport|BaseTransport]][[#asyncio.ReadTransport|ReadTransport]][[#asyncio.WriteTransport|WriteTransport]][[#asyncio.Transport|Transport]]、X1Datagram4X] , [[#asyncio.SubprocessTransport|SubprocessTransport]] 类。
* The [[#protocols|Protocols]] section documents asyncio [[#asyncio.BaseProtocol|<code>BaseProtocol</code>]], [[#asyncio.Protocol|<code>Protocol</code>]], [[#asyncio.BufferedProtocol|<code>BufferedProtocol</code>]], [[#asyncio.DatagramProtocol|<code>DatagramProtocol</code>]], and [[#asyncio.SubprocessProtocol|<code>SubprocessProtocol</code>]] classes.
+
* [[#protocols|Protocols]] 部分记录了 asyncio [[#asyncio.BaseProtocol|BaseProtocol]][[#asyncio.Protocol|Protocol]][[#asyncio.BufferedProtocol|BufferedProtocol]]、DatagramProtocol[X1384X] 和 [X1384X] [X1384X] ] 类。
* The [[#examples|Examples]] section showcases how to work with transports, protocols, and low-level event loop APIs.
+
* [[#examples|示例]] 部分展示了如何使用传输、协议和低级事件循环 API。
  
 
<div id="transports" class="section">
 
<div id="transports" class="section">
  
 
<span id="asyncio-transport"></span>
 
<span id="asyncio-transport"></span>
== Transports ==
+
== 运输 ==
  
'''Source code:''' [https://github.com/python/cpython/tree/3.9/Lib/asyncio/transports.py Lib/asyncio/transports.py]
+
'''源代码:''' [[#id1|<span id="id2" class="problematic">:source:`Lib/asyncio/transsports.py`</span>]]
  
Transports are classes provided by [[../asyncio#module-asyncio|<code>asyncio</code>]] in order to abstract
 
various kinds of communication channels.
 
  
Transport objects are always instantiated by an
+
-----
[[../asyncio-eventloop#asyncio-event-loop|<span class="std std-ref">asyncio event loop</span>]].
 
  
asyncio implements transports for TCP, UDP, SSL, and subprocess pipes.
+
传输是 [[../asyncio#module-asyncio|asyncio]] 提供的类,用于抽象各种通信通道。
The methods available on a transport depend on the transport's kind.
 
  
The transport classes are [[../asyncio-dev#asyncio-multithreading|<span class="std std-ref">not thread safe</span>]].
+
传输对象总是由 [[../asyncio-eventloop#asyncio-event-loop|异步事件循环]] 实例化。
 +
 
 +
asyncio 为 TCP、UDP、SSL 和子进程管道实现传输。 传输上可用的方法取决于传输的种类。
 +
 
 +
传输类 [[../asyncio-dev#asyncio-multithreading|不是线程安全的]]
  
 
<div id="transports-hierarchy" class="section">
 
<div id="transports-hierarchy" class="section">
  
=== Transports Hierarchy ===
+
=== 传输层次结构 ===
  
; ''class'' <code>asyncio.</code><code>BaseTransport</code>
+
; ''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">BaseTransport</span></span>
: Base class for all transports. Contains methods that all asyncio transports share.
+
: 所有传输的基类。 包含所有 asyncio 传输共享的方法。
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>WriteTransport</code><span class="sig-paren">(</span>''<span class="n">BaseTransport</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">WriteTransport</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">BaseTransport</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>A base transport for write-only connections.</p>
+
<dd><p>只写连接的基本传输。</p>
<p>Instances of the ''WriteTransport'' class are returned from
+
<p>''WriteTransport'' 类的实例从 <code>loop.connect_write_pipe()</code> 事件循环方法返回,并且也被子进程相关方法使用,如 <code>loop.subprocess_exec()</code></p></dd></dl>
the [[../asyncio-eventloop#asyncio.loop|<code>loop.connect_write_pipe()</code>]] event loop method and
 
are also used by subprocess-related methods like
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.subprocess_exec()</code>]].</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>ReadTransport</code><span class="sig-paren">(</span>''<span class="n">BaseTransport</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">ReadTransport</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">BaseTransport</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>A base transport for read-only connections.</p>
+
<dd><p>只读连接的基本传输。</p>
<p>Instances of the ''ReadTransport'' class are returned from
+
<p>''ReadTransport'' 类的实例从 <code>loop.connect_read_pipe()</code> 事件循环方法返回,也被子进程相关方法使用,如 <code>loop.subprocess_exec()</code></p></dd></dl>
the [[../asyncio-eventloop#asyncio.loop|<code>loop.connect_read_pipe()</code>]] event loop method and
 
are also used by subprocess-related methods like
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.subprocess_exec()</code>]].</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>Transport</code><span class="sig-paren">(</span>''<span class="n">WriteTransport</span>'', ''<span class="n">ReadTransport</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">Transport</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">WriteTransport</span></span>'', ''<span class="n"><span class="pre">ReadTransport</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Interface representing a bidirectional transport, such as a
+
<dd><p>表示双向传输的接口,例如 TCP 连接。</p>
TCP connection.</p>
+
<p>用户不直接实例化传输; 他们调用一个实用函数,将一个协议工厂和其他创建传输和协议所需的信息传递给它。</p>
<p>The user does not instantiate a transport directly; they call a
+
<p>''Transport'' 类的实例由 <code>loop.create_connection()</code><code>loop.create_unix_connection()</code><code>loop.create_server()</code><code>loop.sendfile()</code> 等事件循环方法返回或使用.</p></dd></dl>
utility function, passing it a protocol factory and other
 
information necessary to create the transport and protocol.</p>
 
<p>Instances of the ''Transport'' class are returned from or used by
 
event loop methods like [[../asyncio-eventloop#asyncio.loop|<code>loop.create_connection()</code>]],
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.create_unix_connection()</code>]],
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.create_server()</code>]], [[../asyncio-eventloop#asyncio.loop|<code>loop.sendfile()</code>]], etc.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>DatagramTransport</code><span class="sig-paren">(</span>''<span class="n">BaseTransport</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">DatagramTransport</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">BaseTransport</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>A transport for datagram (UDP) connections.</p>
+
<dd><p>数据报 (UDP) 连接的传输。</p>
<p>Instances of the ''DatagramTransport'' class are returned from
+
<p>''DatagramTransport'' 类的实例从 <code>loop.create_datagram_endpoint()</code> 事件循环方法返回。</p></dd></dl>
the [[../asyncio-eventloop#asyncio.loop|<code>loop.create_datagram_endpoint()</code>]] event loop method.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>SubprocessTransport</code><span class="sig-paren">(</span>''<span class="n">BaseTransport</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">SubprocessTransport</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">BaseTransport</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>An abstraction to represent a connection between a parent and its
+
<dd><p>表示父操作系统与其子操作系统进程之间的连接的抽象。</p>
child OS process.</p>
+
<p>''SubprocessTransport'' 类的实例从事件循环方法 <code>loop.subprocess_shell()</code> <code>loop.subprocess_exec()</code> 返回。</p></dd></dl>
<p>Instances of the ''SubprocessTransport'' class are returned from
 
event loop methods [[../asyncio-eventloop#asyncio.loop|<code>loop.subprocess_shell()</code>]] and
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.subprocess_exec()</code>]].</p></dd></dl>
 
  
  
第122行: 第88行:
 
<div id="base-transport" class="section">
 
<div id="base-transport" class="section">
  
=== Base Transport ===
+
=== 基地运输 ===
  
 
<dl>
 
<dl>
<dt><code>BaseTransport.</code><code>close</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">BaseTransport.</span></span><span class="sig-name descname"><span class="pre">close</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Close the transport.</p>
+
<dd><p>关闭运输。</p>
<p>If the transport has a buffer for outgoing
+
<p>如果传输具有用于传出数据的缓冲区,则将异步刷新缓冲数据。 将不再接收数据。 刷新所有缓冲数据后,将使用 [[../constants#None|None]] 作为参数调用协议的 [[#asyncio.BaseProtocol.connection_lost|protocol.connection_lost()]] 方法。</p></dd></dl>
data, buffered data will be flushed asynchronously. No more data
 
will be received. After all buffered data is flushed, the
 
protocol's [[#asyncio.BaseProtocol.connection_lost|<code>protocol.connection_lost()</code>]] method will be called with
 
[[../constants#None|<code>None</code>]] as its argument.</p></dd></dl>
 
  
; <code>BaseTransport.</code><code>is_closing</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">BaseTransport.</span></span><span class="sig-name descname"><span class="pre">is_closing</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Return <code>True</code> if the transport is closing or is closed.
+
: 如果传输正在关闭或已关闭,则返回 <code>True</code>
  
 
<dl>
 
<dl>
<dt><code>BaseTransport.</code><code>get_extra_info</code><span class="sig-paren">(</span>''<span class="n">name</span>'', ''<span class="n">default</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">BaseTransport.</span></span><span class="sig-name descname"><span class="pre">get_extra_info</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">name</span></span>'', ''<span class="n"><span class="pre">default</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Return information about the transport or underlying resources
+
<dd><p>返回有关它使用的传输或底层资源的信息。</p>
it uses.</p>
+
<p>''name'' 是一个字符串,表示要获取的传输特定信息。</p>
<p>''name'' is a string representing the piece of transport-specific
+
<p>''default'' 是在信息不可用时返回的值,或者如果传输不支持使用给定的第三方事件循环实现或在当前平台上查询它。</p>
information to get.</p>
+
<p>例如,以下代码尝试获取传输的底层套接字对象:</p>
<p>''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.</p>
 
<p>For example, the following code attempts to get the underlying
 
socket object of the transport:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>sock = transport.get_extra_info('socket')
+
<syntaxhighlight lang="python3">sock = transport.get_extra_info('socket')
 
if sock is not None:
 
if sock is not None:
     print(sock.getsockopt(...))</pre>
+
     print(sock.getsockopt(...))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
<p>Categories of information that can be queried on some transports:</p>
+
<p>可以在某些传输上查询的信息类别:</p>
 
<ul>
 
<ul>
<li><p>socket:</p>
+
<li><p>插座:</p>
 
<ul>
 
<ul>
<li><p><code>'peername'</code>: the remote address to which the socket is
+
<li><p><code>'peername'</code>:socket连接的远程地址,[[../socket#socket.socket|socket.socket.getpeername()]]的结果(<code>None</code>出错)</p></li>
connected, result of [[../socket#socket.socket|<code>socket.socket.getpeername()</code>]]
+
<li><p><code>'socket'</code>: [[../socket#socket|socket.socket]] 实例</p></li>
(<code>None</code> on error)</p></li>
+
<li><p><code>'sockname'</code>:socket自己的地址,[[../socket#socket.socket|socket.socket.getsockname()]]的结果</p></li></ul>
<li><p><code>'socket'</code>: [[../socket#socket|<code>socket.socket</code>]] instance</p></li>
 
<li><p><code>'sockname'</code>: the socket's own address,
 
result of [[../socket#socket.socket|<code>socket.socket.getsockname()</code>]]</p></li></ul>
 
 
</li>
 
</li>
<li><p>SSL socket:</p>
+
<li><p>SSL 套接字:</p>
 
<ul>
 
<ul>
<li><p><code>'compression'</code>: the compression algorithm being used as a
+
<li><p><code>'compression'</code>:作为字符串使用的压缩算法,如果连接未压缩,则为 <code>None</code>[[../ssl#ssl.SSLSocket|ssl.SSLSocket.compression()]] 的结果</p></li>
string, or <code>None</code> if the connection isn't compressed; result
+
<li><p><code>'cipher'</code>:一个三值元组,包含所用密码的名称、定义其用途的 SSL 协议版本以及所使用的秘密位数; [[../ssl#ssl.SSLSocket|ssl.SSLSocket.cipher()]] 的结果</p></li>
of [[../ssl#ssl.SSLSocket|<code>ssl.SSLSocket.compression()</code>]]</p></li>
+
<li><p><code>'peercert'</code>:对等证书; [[../ssl#ssl.SSLSocket|ssl.SSLSocket.getpeercert()]] 的结果</p></li>
<li><p><code>'cipher'</code>: a three-value tuple containing the name of the
+
<li><p><code>'sslcontext'</code>[[../ssl#ssl|ssl.SSLContext]] 实例</p></li>
cipher being used, the version of the SSL protocol that defines
+
<li><p><code>'ssl_object'</code>: [[../ssl#ssl|ssl.SSLObject]] [[../ssl#ssl|ssl.SSLSocket]] 实例</p></li></ul>
its use, and the number of secret bits being used; result of
 
[[../ssl#ssl.SSLSocket|<code>ssl.SSLSocket.cipher()</code>]]</p></li>
 
<li><p><code>'peercert'</code>: peer certificate; result of
 
[[../ssl#ssl.SSLSocket|<code>ssl.SSLSocket.getpeercert()</code>]]</p></li>
 
<li><p><code>'sslcontext'</code>: [[../ssl#ssl|<code>ssl.SSLContext</code>]] instance</p></li>
 
<li><p><code>'ssl_object'</code>: [[../ssl#ssl|<code>ssl.SSLObject</code>]] or
 
[[../ssl#ssl|<code>ssl.SSLSocket</code>]] instance</p></li></ul>
 
 
</li>
 
</li>
<li><p>pipe:</p>
+
<li><p>管道:</p>
 
<ul>
 
<ul>
<li><p><code>'pipe'</code>: pipe object</p></li></ul>
+
<li><p><code>'pipe'</code>:管道对象</p></li></ul>
 
</li>
 
</li>
<li><p>subprocess:</p>
+
<li><p>子流程:</p>
 
<ul>
 
<ul>
<li><p><code>'subprocess'</code>: [[../subprocess#subprocess|<code>subprocess.Popen</code>]] instance</p></li></ul>
+
<li><p><code>'subprocess'</code>: [[../subprocess#subprocess|subprocess.Popen]] 实例</p></li></ul>
 
</li></ul>
 
</li></ul>
 
</dd></dl>
 
</dd></dl>
  
 
<dl>
 
<dl>
<dt><code>BaseTransport.</code><code>set_protocol</code><span class="sig-paren">(</span>''<span class="n">protocol</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">BaseTransport.</span></span><span class="sig-name descname"><span class="pre">set_protocol</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">protocol</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Set a new protocol.</p>
+
<dd><p>设置新协议。</p>
<p>Switching protocol should only be done when both
+
<p>仅当两种协议都记录为支持切换时,才应执行切换协议。</p></dd></dl>
protocols are documented to support the switch.</p></dd></dl>
 
  
; <code>BaseTransport.</code><code>get_protocol</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">BaseTransport.</span></span><span class="sig-name descname"><span class="pre">get_protocol</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Return the current protocol.
+
: 返回当前协议。
  
  
第208行: 第153行:
 
<div id="read-only-transports" class="section">
 
<div id="read-only-transports" class="section">
  
=== Read-only Transports ===
+
=== 只读传输 ===
  
 
<dl>
 
<dl>
<dt><code>ReadTransport.</code><code>is_reading</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">ReadTransport.</span></span><span class="sig-name descname"><span class="pre">is_reading</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return <code>True</code> if the transport is receiving new data.</p>
+
<dd><p>如果传输正在接收新数据,则返回 <code>True</code></p>
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.7 新版功能.</span></p>
+
<p><span class="versionmodified added">3.7 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>ReadTransport.</code><code>pause_reading</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">ReadTransport.</span></span><span class="sig-name descname"><span class="pre">pause_reading</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Pause the receiving end of the transport. No data will be passed to
+
<dd><p>暂停传输的接收端。 在调用 [[#asyncio.ReadTransport.resume_reading|resume_reading()]] 之前,不会将数据传递给协议的 [[#asyncio.Protocol.data_received|protocol.data_received()]] 方法。</p>
the protocol's [[#asyncio.Protocol.data_received|<code>protocol.data_received()</code>]]
 
method until [[#asyncio.ReadTransport.resume_reading|<code>resume_reading()</code>]] is called.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.7 版更改: </span>The method is idempotent, i.e. it can be called when the
+
<p><span class="versionmodified changed">3.7版本变化:</span>方法是幂等的,即 当传输已经暂停或关闭时可以调用它。</p>
transport is already paused or closed.</p>
 
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>ReadTransport.</code><code>resume_reading</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">ReadTransport.</span></span><span class="sig-name descname"><span class="pre">resume_reading</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Resume the receiving end. The protocol's
+
<dd><p>恢复接收端。 如果某些数据可供读取,协议的 [[#asyncio.Protocol.data_received|protocol.data_received()]] 方法将再次调用。</p>
[[#asyncio.Protocol.data_received|<code>protocol.data_received()</code>]] method
 
will be called once again if some data is available for reading.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.7 版更改: </span>The method is idempotent, i.e. it can be called when the
+
<p><span class="versionmodified changed">3.7版本变化:</span>方法是幂等的,即 当传输已经读取时可以调用它。</p>
transport is already reading.</p>
 
  
 
</div></dd></dl>
 
</div></dd></dl>
第247行: 第186行:
 
<div id="write-only-transports" class="section">
 
<div id="write-only-transports" class="section">
  
=== Write-only Transports ===
+
=== 只写传输 ===
  
; <code>WriteTransport.</code><code>abort</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">WriteTransport.</span></span><span class="sig-name descname"><span class="pre">abort</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: 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 [[#asyncio.BaseProtocol.connection_lost|<code>protocol.connection_lost()</code>]] method will eventually be called with [[../constants#None|<code>None</code>]] as its argument.
+
: 立即关闭传输,无需等待挂起的操作完成。 缓冲的数据将丢失。 将不再接收数据。 协议的 [[#asyncio.BaseProtocol.connection_lost|protocol.connection_lost()]] 方法最终将使用 [[../constants#None|None]] 作为参数调用。
  
; <code>WriteTransport.</code><code>can_write_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">WriteTransport.</span></span><span class="sig-name descname"><span class="pre">can_write_eof</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Return [[../constants#True|<code>True</code>]] if the transport supports [[#asyncio.WriteTransport.write_eof|<code>write_eof()</code>]], [[../constants#False|<code>False</code>]] if not.
+
: 如果传输支持 [[#asyncio.WriteTransport.write_eof|write_eof()]],则返回 [[../constants#True|True]],否则返回 [[../constants#False|False]]
  
; <code>WriteTransport.</code><code>get_write_buffer_size</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">WriteTransport.</span></span><span class="sig-name descname"><span class="pre">get_write_buffer_size</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Return the current size of the output buffer used by the transport.
+
: 返回传输使用的输出缓冲区的当前大小。
  
 
<dl>
 
<dl>
<dt><code>WriteTransport.</code><code>get_write_buffer_limits</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">WriteTransport.</span></span><span class="sig-name descname"><span class="pre">get_write_buffer_limits</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Get the ''high'' and ''low'' watermarks for write flow control. Return a
+
<dd><p>获取 ''high'' ''low'' 水印用于写流控制。 返回一个元组 <code>(low, high)</code>,其中 ''low'' ''high'' 是正字节数。</p>
tuple <code>(low, high)</code> where ''low'' and ''high'' are positive number of
+
<p>使用 [[#asyncio.WriteTransport.set_write_buffer_limits|set_write_buffer_limits()]] 设置限制。</p>
bytes.</p>
 
<p>Use [[#asyncio.WriteTransport.set_write_buffer_limits|<code>set_write_buffer_limits()</code>]] to set the limits.</p>
 
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.4.2 新版功能.</span></p>
+
<p><span class="versionmodified added">版本 3.4.2 中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>WriteTransport.</code><code>set_write_buffer_limits</code><span class="sig-paren">(</span>''<span class="n">high</span><span class="o">=</span><span class="default_value">None</span>'', ''<span class="n">low</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">WriteTransport.</span></span><span class="sig-name descname"><span class="pre">set_write_buffer_limits</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">high</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>'', ''<span class="n"><span class="pre">low</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Set the ''high'' and ''low'' watermarks for write flow control.</p>
+
<dd><p>设置''high''''low''水印进行写流控制。</p>
<p>These two values (measured in number of
+
<p>这两个值(以字节数衡量)控制何时调用协议的 [[#asyncio.BaseProtocol.pause_writing|protocol.pause_writing()]] [[#asyncio.BaseProtocol.resume_writing|protocol.resume_writing()]] 方法。 如果指定,低水印必须小于或等于高水印。 ''high'' ''low'' 都不能为负数。</p>
bytes) control when the protocol's
+
<p>[[#asyncio.BaseProtocol.pause_writing|pause_writing()]] 当缓冲区大小变得大于或等于 ''high'' 值时调用。 如果写入已暂停,则在缓冲区大小小于或等于 ''low'' 值时调用 [[#asyncio.BaseProtocol.resume_writing|resume_writing()]]</p>
[[#asyncio.BaseProtocol.pause_writing|<code>protocol.pause_writing()</code>]]
+
<p>默认值是特定于实现的。 如果仅给出高水印,则低水印默认为小于或等于高水印的特定于实现的值。 将 ''high'' 设置为零也会强制 ''low'' 为零,并导致每当缓冲区变为非空时调用 [[#asyncio.BaseProtocol.pause_writing|pause_writing()]]。 将 ''low'' 设置为零会导致 [[#asyncio.BaseProtocol.resume_writing|resume_writing()]] 仅在缓冲区为空时调用。 对任一限制使用零通常是次优的,因为它减少了同时进行 I/O 和计算的机会。</p>
and [[#asyncio.BaseProtocol.resume_writing|<code>protocol.resume_writing()</code>]]
+
<p>使用 [[#asyncio.WriteTransport.get_write_buffer_limits|get_write_buffer_limits()]] 获取限制。</p></dd></dl>
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.</p>
 
<p>[[#asyncio.BaseProtocol.pause_writing|<code>pause_writing()</code>]] is called when the buffer size
 
becomes greater than or equal to the ''high'' value. If writing has
 
been paused, [[#asyncio.BaseProtocol.resume_writing|<code>resume_writing()</code>]] is called when
 
the buffer size becomes less than or equal to the ''low'' value.</p>
 
<p>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 [[#asyncio.BaseProtocol.pause_writing|<code>pause_writing()</code>]] to be called
 
whenever the buffer becomes non-empty. Setting ''low'' to zero causes
 
[[#asyncio.BaseProtocol.resume_writing|<code>resume_writing()</code>]] 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.</p>
 
<p>Use [[#asyncio.WriteTransport.get_write_buffer_limits|<code>get_write_buffer_limits()</code>]]
 
to get the limits.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>WriteTransport.</code><code>write</code><span class="sig-paren">(</span>''<span class="n">data</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">WriteTransport.</span></span><span class="sig-name descname"><span class="pre">write</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">data</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Write some ''data'' bytes to the transport.</p>
+
<dd><p>将一些 ''data'' 字节写入传输。</p>
<p>This method does not block; it buffers the data and arranges for it
+
<p>这个方法不会阻塞; 它缓冲数据并安排它异步发送。</p></dd></dl>
to be sent out asynchronously.</p></dd></dl>
 
  
; <code>WriteTransport.</code><code>writelines</code><span class="sig-paren">(</span>''<span class="n">list_of_data</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">WriteTransport.</span></span><span class="sig-name descname"><span class="pre">writelines</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">list_of_data</span></span>''<span class="sig-paren">)</span>
: Write a list (or any iterable) of data bytes to the transport. This is functionally equivalent to calling [[#asyncio.WriteTransport.write|<code>write()</code>]] on each element yielded by the iterable, but may be implemented more efficiently.
+
: 将数据字节的列表(或任何可迭代的)写入传输。 这在功能上等同于对迭代产生的每个元素调用 [[#asyncio.WriteTransport.write|write()]],但可以更有效地实现。
  
 
<dl>
 
<dl>
<dt><code>WriteTransport.</code><code>write_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">WriteTransport.</span></span><span class="sig-name descname"><span class="pre">write_eof</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Close the write end of the transport after flushing all buffered data.
+
<dd><p>刷新所有缓冲数据后关闭传输的写入端。 可能仍会收到数据。</p>
Data may still be received.</p>
+
<p>如果传输(例如 SSL) 不支持半封闭连接。</p></dd></dl>
<p>This method can raise [[../exceptions#NotImplementedError|<code>NotImplementedError</code>]] if the transport
 
(e.g. SSL) doesn't support half-closed connections.</p></dd></dl>
 
  
  
第317行: 第232行:
 
<div id="datagram-transports" class="section">
 
<div id="datagram-transports" class="section">
  
=== Datagram Transports ===
+
=== 数据报传输 ===
  
 
<dl>
 
<dl>
<dt><code>DatagramTransport.</code><code>sendto</code><span class="sig-paren">(</span>''<span class="n">data</span>'', ''<span class="n">addr</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">DatagramTransport.</span></span><span class="sig-name descname"><span class="pre">sendto</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">data</span></span>'', ''<span class="n"><span class="pre">addr</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Send the ''data'' bytes to the remote peer given by ''addr'' (a
+
<dd><p>''data'' 字节发送到由 ''addr''(依赖于传输的目标地址)给出的远程对等方。 如果 ''addr'' [[../constants#None|None]],则数据将发送到传输创建时给定的目标地址。</p>
transport-dependent target address). If ''addr'' is [[../constants#None|<code>None</code>]],
+
<p>这个方法不会阻塞; 它缓冲数据并安排它异步发送。</p></dd></dl>
the data is sent to the target address given on transport
 
creation.</p>
 
<p>This method does not block; it buffers the data and arranges
 
for it to be sent out asynchronously.</p></dd></dl>
 
  
; <code>DatagramTransport.</code><code>abort</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">DatagramTransport.</span></span><span class="sig-name descname"><span class="pre">abort</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: 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 [[#asyncio.BaseProtocol.connection_lost|<code>protocol.connection_lost()</code>]] method will eventually be called with [[../constants#None|<code>None</code>]] as its argument.
+
: 立即关闭传输,无需等待挂起的操作完成。 缓冲的数据将丢失。 将不再接收数据。 协议的 [[#asyncio.BaseProtocol.connection_lost|protocol.connection_lost()]] 方法最终将使用 [[../constants#None|None]] 作为参数调用。
  
  
第336行: 第247行:
  
 
<span id="asyncio-subprocess-transports"></span>
 
<span id="asyncio-subprocess-transports"></span>
=== Subprocess Transports ===
+
=== 子流程传输 ===
  
; <code>SubprocessTransport.</code><code>get_pid</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">SubprocessTransport.</span></span><span class="sig-name descname"><span class="pre">get_pid</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Return the subprocess process id as an integer.
+
: 以整数形式返回子进程进程 ID。
  
; <code>SubprocessTransport.</code><code>get_pipe_transport</code><span class="sig-paren">(</span>''<span class="n">fd</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">SubprocessTransport.</span></span><span class="sig-name descname"><span class="pre">get_pipe_transport</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">fd</span></span>''<span class="sig-paren">)</span>
: Return the transport for the communication pipe corresponding to the integer file descriptor ''fd'':
+
: 返回与整数文件描述符 ''fd'' 对应的通信管道的传输:
;* <code>0</code>: readable streaming transport of the standard input (''stdin''), or [[../constants#None|<code>None</code>]] if the subprocess was not created with <code>stdin=PIPE</code>
+
;* <code>0</code>:标准输入的可读流传输 (''stdin''),或者 [[../constants#None|None]] 如果子进程不是用 <code>stdin=PIPE</code> 创建的
;* <code>1</code>: writable streaming transport of the standard output (''stdout''), or [[../constants#None|<code>None</code>]] if the subprocess was not created with <code>stdout=PIPE</code>
+
;* <code>1</code>:标准输出的可写流传输 (''stdout''),或者 [[../constants#None|None]] 如果子进程不是用 <code>stdout=PIPE</code> 创建的
;* <code>2</code>: writable streaming transport of the standard error (''stderr''), or [[../constants#None|<code>None</code>]] if the subprocess was not created with <code>stderr=PIPE</code>
+
;* <code>2</code>:标准错误的可写流传输 (''stderr''),或者 [[../constants#None|None]] 如果子进程不是用 <code>stderr=PIPE</code> 创建的
;* other ''fd'': [[../constants#None|<code>None</code>]]
+
;* 其他 ''fd'': [[../constants#None|]]
  
; <code>SubprocessTransport.</code><code>get_returncode</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">SubprocessTransport.</span></span><span class="sig-name descname"><span class="pre">get_returncode</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Return the subprocess return code as an integer or [[../constants#None|<code>None</code>]] if it hasn't returned, which is similar to the [[../subprocess#subprocess.Popen|<code>subprocess.Popen.returncode</code>]] attribute.
+
: 将子进程返回码作为整数返回,如果没有返回,则返回 [[../constants#None|None]],类似于 [[../subprocess#subprocess.Popen|subprocess.Popen.returncode]] 属性。
  
 
<dl>
 
<dl>
<dt><code>SubprocessTransport.</code><code>kill</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">SubprocessTransport.</span></span><span class="sig-name descname"><span class="pre">kill</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Kill the subprocess.</p>
+
<dd><p>杀死子进程。</p>
<p>On POSIX systems, the function sends SIGKILL to the subprocess.
+
<p>POSIX 系统上,该函数将 SIGKILL 发送到子进程。 在 Windows 上,此方法是 [[#asyncio.SubprocessTransport.terminate|terminate()]] 的别名。</p>
On Windows, this method is an alias for [[#asyncio.SubprocessTransport.terminate|<code>terminate()</code>]].</p>
+
<p>另见 [[../subprocess#subprocess.Popen|subprocess.Popen.kill()]]</p></dd></dl>
<p>See also [[../subprocess#subprocess.Popen|<code>subprocess.Popen.kill()</code>]].</p></dd></dl>
 
  
; <code>SubprocessTransport.</code><code>send_signal</code><span class="sig-paren">(</span>''<span class="n">signal</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">SubprocessTransport.</span></span><span class="sig-name descname"><span class="pre">send_signal</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">signal</span></span>''<span class="sig-paren">)</span>
: Send the ''signal'' number to the subprocess, as in [[../subprocess#subprocess.Popen|<code>subprocess.Popen.send_signal()</code>]].
+
: ''信号'' 编号发送到子进程,如 [[../subprocess#subprocess.Popen|subprocess.Popen.send_signal()]]
  
 
<dl>
 
<dl>
<dt><code>SubprocessTransport.</code><code>terminate</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">SubprocessTransport.</span></span><span class="sig-name descname"><span class="pre">terminate</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Stop the subprocess.</p>
+
<dd><p>停止子进程。</p>
<p>On POSIX systems, this method sends SIGTERM to the subprocess.
+
<p>POSIX 系统上,此方法将 SIGTERM 发送到子进程。 在 Windows 上,调用 Windows API 函数 TerminateProcess() 来停止子进程。</p>
On Windows, the Windows API function TerminateProcess() is called to
+
<p>另见 [[../subprocess#subprocess.Popen|subprocess.Popen.terminate()]]</p></dd></dl>
stop the subprocess.</p>
 
<p>See also [[../subprocess#subprocess.Popen|<code>subprocess.Popen.terminate()</code>]].</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>SubprocessTransport.</code><code>close</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">SubprocessTransport.</span></span><span class="sig-name descname"><span class="pre">close</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Kill the subprocess by calling the [[#asyncio.SubprocessTransport.kill|<code>kill()</code>]] method.</p>
+
<dd><p>通过调用 [[#asyncio.SubprocessTransport.kill|kill()]] 方法终止子进程。</p>
<p>If the subprocess hasn't returned yet, and close transports of
+
<p>如果子进程尚未返回,则关闭 ''stdin''''stdout'' ''stderr'' 管道的传输。</p></dd></dl>
''stdin'', ''stdout'', and ''stderr'' pipes.</p></dd></dl>
 
  
  
第382行: 第289行:
  
 
<span id="asyncio-protocol"></span>
 
<span id="asyncio-protocol"></span>
== Protocols ==
+
== 协议 ==
 +
 
 +
'''源代码:''' [[#id3|<span id="id4" class="problematic">:source:`Lib/asyncio/protocols.py`</span>]]
 +
 
  
'''Source code:''' [https://github.com/python/cpython/tree/3.9/Lib/asyncio/protocols.py Lib/asyncio/protocols.py]
+
-----
  
asyncio provides a set of abstract base classes that should be used
+
asyncio 提供了一组用于实现网络协议的抽象基类。 这些类旨在与 [[#asyncio-transport|传输]] 一起使用。
to implement network protocols. Those classes are meant to be used
 
together with [[#asyncio-transport|<span class="std std-ref">transports</span>]].
 
  
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.
 
  
 
<div id="base-protocols" class="section">
 
<div id="base-protocols" class="section">
  
=== Base Protocols ===
+
=== 基本协议 ===
  
; ''class'' <code>asyncio.</code><code>BaseProtocol</code>
+
; ''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">BaseProtocol</span></span>
: Base protocol with methods that all protocols share.
+
: 具有所有协议共享的方法的基本协议。
  
; ''class'' <code>asyncio.</code><code>Protocol</code><span class="sig-paren">(</span>''<span class="n">BaseProtocol</span>''<span class="sig-paren">)</span>
+
; ''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">Protocol</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">BaseProtocol</span></span>''<span class="sig-paren">)</span>
: The base class for implementing streaming protocols (TCP, Unix sockets, etc).
+
: 用于实现流协议(TCP、Unix 套接字等)的基类。
  
; ''class'' <code>asyncio.</code><code>BufferedProtocol</code><span class="sig-paren">(</span>''<span class="n">BaseProtocol</span>''<span class="sig-paren">)</span>
+
; ''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">BufferedProtocol</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">BaseProtocol</span></span>''<span class="sig-paren">)</span>
: A base class for implementing streaming protocols with manual control of the receive buffer.
+
: 用于通过手动控制接收缓冲区来实现流协议的基类。
  
; ''class'' <code>asyncio.</code><code>DatagramProtocol</code><span class="sig-paren">(</span>''<span class="n">BaseProtocol</span>''<span class="sig-paren">)</span>
+
; ''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">DatagramProtocol</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">BaseProtocol</span></span>''<span class="sig-paren">)</span>
: The base class for implementing datagram (UDP) protocols.
+
: 用于实现数据报 (UDP) 协议的基类。
  
; ''class'' <code>asyncio.</code><code>SubprocessProtocol</code><span class="sig-paren">(</span>''<span class="n">BaseProtocol</span>''<span class="sig-paren">)</span>
+
; ''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">SubprocessProtocol</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">BaseProtocol</span></span>''<span class="sig-paren">)</span>
: The base class for implementing protocols communicating with child processes (unidirectional pipes).
+
: 用于实现与子进程(单向管道)通信的协议的基类。
  
  
第418行: 第323行:
 
<div id="base-protocol" class="section">
 
<div id="base-protocol" class="section">
  
=== Base Protocol ===
+
=== 基础协议 ===
  
All asyncio protocols can implement Base Protocol callbacks.
+
所有 asyncio 协议都可以实现 Base Protocol 回调。
  
Connection 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.
 
  
 
<dl>
 
<dl>
<dt><code>BaseProtocol.</code><code>connection_made</code><span class="sig-paren">(</span>''<span class="n">transport</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">BaseProtocol.</span></span><span class="sig-name descname"><span class="pre">connection_made</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">transport</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Called when a connection is made.</p>
+
<dd><p>建立连接时调用。</p>
<p>The ''transport'' argument is the transport representing the
+
<p>''transport'' 参数是表示连接的传输。 该协议负责存储对其传输的引用。</p></dd></dl>
connection. The protocol is responsible for storing the reference
 
to its transport.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>BaseProtocol.</code><code>connection_lost</code><span class="sig-paren">(</span>''<span class="n">exc</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">BaseProtocol.</span></span><span class="sig-name descname"><span class="pre">connection_lost</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">exc</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Called when the connection is lost or closed.</p>
+
<dd><p>当连接丢失或关闭时调用。</p>
<p>The argument is either an exception object or [[../constants#None|<code>None</code>]].
+
<p>参数是异常对象或 [[../constants#None|None]]。 后者意味着接收到常规 EOF,或者连接被连接的这一侧中止或关闭。</p></dd></dl>
The latter means a regular EOF is received, or the connection was
 
aborted or closed by this side of the connection.</p></dd></dl>
 
  
Flow Control Callbacks
+
流控制回调
  
Flow control callbacks can be called by transports to pause or
+
传输可以调用流控制回调来暂停或恢复协议执行的写入。
resume writing performed by the protocol.
 
  
See the documentation of the [[#asyncio.WriteTransport.set_write_buffer_limits|<code>set_write_buffer_limits()</code>]]
+
有关更多详细信息,请参阅 [[#asyncio.WriteTransport.set_write_buffer_limits|set_write_buffer_limits()]] 方法的文档。
method for more details.
 
  
; <code>BaseProtocol.</code><code>pause_writing</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">BaseProtocol.</span></span><span class="sig-name descname"><span class="pre">pause_writing</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Called when the transport's buffer goes over the high watermark.
+
: 当传输的缓冲区超过高水位线时调用。
  
; <code>BaseProtocol.</code><code>resume_writing</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">BaseProtocol.</span></span><span class="sig-name descname"><span class="pre">resume_writing</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Called when the transport's buffer drains below the low watermark.
+
: 当传输的缓冲区耗尽低于低水位线时调用。
  
If the buffer size equals the high watermark,
+
如果缓冲区大小等于高水印,则不调用 [[#asyncio.BaseProtocol.pause_writing|pause_writing()]]:缓冲区大小必须严格超过。
[[#asyncio.BaseProtocol.pause_writing|<code>pause_writing()</code>]] is not called: the buffer size must
 
go strictly over.
 
  
Conversely, [[#asyncio.BaseProtocol.resume_writing|<code>resume_writing()</code>]] is called when the
+
相反,当缓冲区大小等于或小于低水印时,会调用 [[#asyncio.BaseProtocol.resume_writing|resume_writing()]]。 当任一标记为零时,这些结束条件对于确保事情按预期进行非常重要。
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.
 
  
  
第469行: 第361行:
 
<div id="streaming-protocols" class="section">
 
<div id="streaming-protocols" class="section">
  
=== Streaming Protocols ===
+
=== 流媒体协议 ===
  
Event methods, such as [[../asyncio-eventloop#asyncio.loop|<code>loop.create_server()</code>]],
+
事件方法,例如 <code>loop.create_server()</code><code>loop.create_unix_server()</code><code>loop.create_connection()</code><code>loop.create_unix_connection()</code><code>loop.connect_accepted_socket()</code><code>loop.connect_read_pipe()</code> <code>loop.connect_write_pipe()</code> 接受返回流协议的工厂。
[[../asyncio-eventloop#asyncio.loop|<code>loop.create_unix_server()</code>]], [[../asyncio-eventloop#asyncio.loop|<code>loop.create_connection()</code>]],
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.create_unix_connection()</code>]], [[../asyncio-eventloop#asyncio.loop|<code>loop.connect_accepted_socket()</code>]],
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.connect_read_pipe()</code>]], and [[../asyncio-eventloop#asyncio.loop|<code>loop.connect_write_pipe()</code>]]
 
accept factories that return streaming protocols.
 
  
 
<dl>
 
<dl>
<dt><code>Protocol.</code><code>data_received</code><span class="sig-paren">(</span>''<span class="n">data</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">Protocol.</span></span><span class="sig-name descname"><span class="pre">data_received</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">data</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Called when some data is received. ''data'' is a non-empty bytes
+
<dd><p>当接收到一些数据时调用。 ''data'' 是一个包含传入数据的非空字节对象。</p>
object containing the incoming data.</p>
+
<p>数据是缓冲、分块还是重组取决于传输。 通常,您不应依赖特定的语义,而应使解析通用且灵活。 但是,数据总是以正确的顺序接收。</p>
<p>Whether the data is buffered, chunked or reassembled depends on
+
<p>该方法可以在连接打开时调用任意次数。</p>
the transport. In general, you shouldn't rely on specific semantics
+
<p>然而, [[#asyncio.Protocol.eof_received|protocol.eof_received()]] 最多被调用一次。 一旦 eof_received() 被调用,<code>data_received()</code> 就不再被调用。</p></dd></dl>
and instead make your parsing generic and flexible. However,
 
data is always received in the correct order.</p>
 
<p>The method can be called an arbitrary number of times while
 
a connection is open.</p>
 
<p>However, [[#asyncio.Protocol.eof_received|<code>protocol.eof_received()</code>]]
 
is called at most once. Once eof_received() is called,
 
<code>data_received()</code> is not called anymore.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>Protocol.</code><code>eof_received</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">Protocol.</span></span><span class="sig-name descname"><span class="pre">eof_received</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called when the other end signals it won't send any more data
+
<dd><p>当另一端发出信号不会再发送任何数据时调用(例如通过调用 [[#asyncio.WriteTransport.write_eof|transport.write_eof()]],如果另一端也使用 asyncio)。</p>
(for example by calling [[#asyncio.WriteTransport.write_eof|<code>transport.write_eof()</code>]], if the other end also uses
+
<p>此方法可能会返回一个错误值(包括 <code>None</code>),在这种情况下传输将自行关闭。 相反,如果此方法返回真值,则使用的协议确定是否关闭传输。 由于默认实现返回 <code>None</code>,它隐式关闭连接。</p>
asyncio).</p>
+
<p>某些传输(包括 SSL)不支持半关闭连接,在这种情况下,从此方法返回 true 将导致连接被关闭。</p></dd></dl>
<p>This method may return a false value (including <code>None</code>), 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 <code>None</code>, it implicitly closes the
 
connection.</p>
 
<p>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.</p></dd></dl>
 
  
State machine:
+
状态机:
  
 
<div class="highlight-none notranslate">
 
<div class="highlight-none notranslate">
第511行: 第384行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>start -&gt; connection_made
+
<pre class="none">start -&gt; connection_made
 
     [-&gt; data_received]*
 
     [-&gt; data_received]*
 
     [-&gt; eof_received]?
 
     [-&gt; eof_received]?
第523行: 第396行:
 
<div id="buffered-streaming-protocols" class="section">
 
<div id="buffered-streaming-protocols" class="section">
  
=== Buffered Streaming Protocols ===
+
=== 缓冲流协议 ===
  
 
<div class="versionadded">
 
<div class="versionadded">
  
<span class="versionmodified added">3.7 新版功能.</span>
+
<span class="versionmodified added">3.7 版中的新功能。</span>
  
  
 
</div>
 
</div>
Buffered Protocols can be used with any event loop method
+
缓冲协议可以与任何支持 [[#streaming-protocols|流协议]] 的事件循环方法一起使用。
that supports [[#streaming-protocols|Streaming Protocols]].
 
  
<code>BufferedProtocol</code> implementations allow explicit manual allocation
+
<code>BufferedProtocol</code> 实现允许显式手动分配和控制接收缓冲区。 然后事件循环可以使用协议提供的缓冲区来避免不必要的数据复制。 这可以显着提高接收大量数据的协议的性能。 复杂的协议实现可以显着减少缓冲区分配的数量。
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 [[#asyncio.BufferedProtocol|<code>BufferedProtocol</code>]]
+
[[#asyncio.BufferedProtocol|BufferedProtocol]] 实例上调用以下回调:
instances:
 
  
 
<dl>
 
<dl>
<dt><code>BufferedProtocol.</code><code>get_buffer</code><span class="sig-paren">(</span>''<span class="n">sizehint</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">BufferedProtocol.</span></span><span class="sig-name descname"><span class="pre">get_buffer</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">sizehint</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Called to allocate a new receive buffer.</p>
+
<dd><p>调用以分配新的接收缓冲区。</p>
<p>''sizehint'' is the recommended minimum size for the returned
+
<p>''sizehint'' 是推荐的返回缓冲区的最小大小。 返回比 ''sizehint'' 建议的更小或更大的缓冲区是可以接受的。 当设置为 -1 时,缓冲区大小可以是任意的。 返回大小为零的缓冲区是错误的。</p>
buffer. It is acceptable to return smaller or larger buffers
+
<p><code>get_buffer()</code> 必须返回一个实现 [[../../c-api/buffer#bufferobjects|缓冲协议]] 的对象。</p></dd></dl>
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.</p>
 
<p><code>get_buffer()</code> must return an object implementing the
 
[[../../c-api/buffer#bufferobjects|<span class="std std-ref">buffer protocol</span>]].</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>BufferedProtocol.</code><code>buffer_updated</code><span class="sig-paren">(</span>''<span class="n">nbytes</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">BufferedProtocol.</span></span><span class="sig-name descname"><span class="pre">buffer_updated</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">nbytes</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Called when the buffer was updated with the received data.</p>
+
<dd><p>在使用接收到的数据更新缓冲区时调用。</p>
<p>''nbytes'' is the total number of bytes that were written to the buffer.</p></dd></dl>
+
<p>''nbytes'' 是写入缓冲区的总字节数。</p></dd></dl>
  
; <code>BufferedProtocol.</code><code>eof_received</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">BufferedProtocol.</span></span><span class="sig-name descname"><span class="pre">eof_received</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: See the documentation of the [[#asyncio.Protocol.eof_received|<code>protocol.eof_received()</code>]] method.
+
: 请参阅 [[#asyncio.Protocol.eof_received|protocol.eof_received()]] 方法的文档。
  
[[#asyncio.BufferedProtocol.get_buffer|<code>get_buffer()</code>]] can be called an arbitrary number
+
[[#asyncio.BufferedProtocol.get_buffer|get_buffer()]] 在连接期间可以被调用任意次数。 然而, [[#asyncio.Protocol.eof_received|protocol.eof_received()]] 最多被调用一次,如果被调用,[[#asyncio.BufferedProtocol.get_buffer|get_buffer()]] [[#asyncio.BufferedProtocol.buffer_updated|buffer_updated()]] 将不会被调用。
of times during a connection. However, [[#asyncio.Protocol.eof_received|<code>protocol.eof_received()</code>]] is called at most once
 
and, if called, [[#asyncio.BufferedProtocol.get_buffer|<code>get_buffer()</code>]] and
 
[[#asyncio.BufferedProtocol.buffer_updated|<code>buffer_updated()</code>]] won't be called after it.
 
  
State machine:
+
状态机:
  
 
<div class="highlight-none notranslate">
 
<div class="highlight-none notranslate">
第573行: 第432行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>start -&gt; connection_made
+
<pre class="none">start -&gt; connection_made
 
     [-&gt; get_buffer
 
     [-&gt; get_buffer
 
         [-&gt; buffer_updated]?
 
         [-&gt; buffer_updated]?
第587行: 第446行:
 
<div id="datagram-protocols" class="section">
 
<div id="datagram-protocols" class="section">
  
=== Datagram Protocols ===
+
=== 数据报协议 ===
  
Datagram Protocol instances should be constructed by protocol
+
数据报协议实例应该由传递给 <code>loop.create_datagram_endpoint()</code> 方法的协议工厂构造。
factories passed to the [[../asyncio-eventloop#asyncio.loop|<code>loop.create_datagram_endpoint()</code>]] method.
 
  
; <code>DatagramProtocol.</code><code>datagram_received</code><span class="sig-paren">(</span>''<span class="n">data</span>'', ''<span class="n">addr</span>''<span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">DatagramProtocol.</span></span><span class="sig-name descname"><span class="pre">datagram_received</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">data</span></span>'', ''<span class="n"><span class="pre">addr</span></span>''<span class="sig-paren">)</span>
: 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.
+
: 收到数据报时调用。 ''data'' 是一个包含传入数据的字节对象。 ''addr''为发送数据的peer地址; 确切的格式取决于传输。
  
 
<dl>
 
<dl>
<dt><code>DatagramProtocol.</code><code>error_received</code><span class="sig-paren">(</span>''<span class="n">exc</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">DatagramProtocol.</span></span><span class="sig-name descname"><span class="pre">error_received</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">exc</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Called when a previous send or receive operation raises an
+
<dd><p>当先前的发送或接收操作引发 [[../exceptions#OSError|OSError]] 时调用。 ''exc'' [[../exceptions#OSError|OSError]] 实例。</p>
[[../exceptions#OSError|<code>OSError</code>]]. ''exc'' is the [[../exceptions#OSError|<code>OSError</code>]] instance.</p>
+
<p>在极少数情况下调用此方法,当传输(例如 UDP) 检测到数据报无法传送到其接收者。 但在许多情况下,无法传递的数据报将被悄悄丢弃。</p></dd></dl>
<p>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.</p></dd></dl>
 
  
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
On BSD systems (macOS, FreeBSD, etc.) flow control is not supported
+
BSD 系统(macOS、FreeBSD 等)上,数据报协议不支持流量控制,因为没有可靠的方法来检测由于写入过多数据包而导致的发送失败。
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
+
套接字始终显示为“就绪”,多余的数据包将被丢弃。 [[../exceptions#OSError|OSError]] <code>errno</code> 设置为 [[../errno#errno|errno.ENOBUFS]] 可能会也可能不会引发; 如果它被引发,它将被报告给 [[#asyncio.DatagramProtocol.error_received|DatagramProtocol.error_received()]] 但否则会被忽略。
[[../exceptions#OSError|<code>OSError</code>]] with <code>errno</code> set to [[../errno#errno|<code>errno.ENOBUFS</code>]] may
 
or may not be raised; if it is raised, it will be reported to
 
[[#asyncio.DatagramProtocol.error_received|<code>DatagramProtocol.error_received()</code>]] but otherwise ignored.
 
  
  
第624行: 第473行:
  
 
<span id="asyncio-subprocess-protocols"></span>
 
<span id="asyncio-subprocess-protocols"></span>
=== Subprocess Protocols ===
+
=== 子进程协议 ===
  
Datagram Protocol instances should be constructed by protocol
+
子进程协议实例应该由传递给 <code>loop.subprocess_exec()</code> <code>loop.subprocess_shell()</code> 方法的协议工厂构造。
factories passed to the [[../asyncio-eventloop#asyncio.loop|<code>loop.subprocess_exec()</code>]] and
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.subprocess_shell()</code>]] methods.
 
  
 
<dl>
 
<dl>
<dt><code>SubprocessProtocol.</code><code>pipe_data_received</code><span class="sig-paren">(</span>''<span class="n">fd</span>'', ''<span class="n">data</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">SubprocessProtocol.</span></span><span class="sig-name descname"><span class="pre">pipe_data_received</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">fd</span></span>'', ''<span class="n"><span class="pre">data</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Called when the child process writes data into its stdout or stderr
+
<dd><p>当子进程将数据写入其 stdout stderr 管道时调用。</p>
pipe.</p>
+
<p>''fd'' 是管道的整数文件描述符。</p>
<p>''fd'' is the integer file descriptor of the pipe.</p>
+
<p>''data'' 是一个包含接收数据的非空字节对象。</p></dd></dl>
<p>''data'' is a non-empty bytes object containing the received data.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>SubprocessProtocol.</code><code>pipe_connection_lost</code><span class="sig-paren">(</span>''<span class="n">fd</span>'', ''<span class="n">exc</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">SubprocessProtocol.</span></span><span class="sig-name descname"><span class="pre">pipe_connection_lost</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">fd</span></span>'', ''<span class="n"><span class="pre">exc</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Called when one of the pipes communicating with the child process
+
<dd><p>当与子进程通信的管道之一关闭时调用。</p>
is closed.</p>
+
<p>''fd'' 是已关闭的整数文件描述符。</p></dd></dl>
<p>''fd'' is the integer file descriptor that was closed.</p></dd></dl>
 
  
; <code>SubprocessProtocol.</code><code>process_exited</code><span class="sig-paren">(</span><span class="sig-paren">)</span>
+
; <span class="sig-prename descclassname"><span class="pre">SubprocessProtocol.</span></span><span class="sig-name descname"><span class="pre">process_exited</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span>
: Called when the child process has exited.
+
: 当子进程退出时调用。
  
  
第652行: 第497行:
 
<div id="examples" class="section">
 
<div id="examples" class="section">
  
== Examples ==
+
== 例子 ==
  
 
<div id="tcp-echo-server" class="section">
 
<div id="tcp-echo-server" class="section">
  
 
<span id="asyncio-example-tcp-echo-server-protocol"></span>
 
<span id="asyncio-example-tcp-echo-server-protocol"></span>
=== TCP Echo Server ===
+
=== TCP 回声服务器 ===
  
Create a TCP echo server using the [[../asyncio-eventloop#asyncio.loop|<code>loop.create_server()</code>]] method, send back
+
使用 <code>loop.create_server()</code> 方法创建一个 TCP 回显服务器,发送回接收到的数据,并关闭连接:
received data, and close the connection:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第666行: 第510行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
  
  
第699行: 第543行:
  
  
asyncio.run(main())</pre>
+
asyncio.run(main())</syntaxhighlight>
  
 
</div>
 
</div>
第706行: 第550行:
 
<div class="admonition seealso">
 
<div class="admonition seealso">
  
参见
+
也可以看看
  
The [[../asyncio-stream#asyncio-tcp-echo-server-streams|<span class="std std-ref">TCP echo server using streams</span>]]
+
[[../asyncio-stream#asyncio-tcp-echo-server-streams|TCP 回显服务器使用流]] 示例使用高级 <code>asyncio.start_server()</code> 函数。
example uses the high-level [[../asyncio-stream#asyncio|<code>asyncio.start_server()</code>]] function.
 
  
  
第718行: 第561行:
  
 
<span id="asyncio-example-tcp-echo-client-protocol"></span>
 
<span id="asyncio-example-tcp-echo-client-protocol"></span>
=== TCP Echo Client ===
+
=== TCP 回显客户端 ===
  
A TCP echo client using the [[../asyncio-eventloop#asyncio.loop|<code>loop.create_connection()</code>]] method, sends
+
使用 <code>loop.create_connection()</code> 方法的 TCP 回显客户端发送数据,并等待连接关闭:
data, and waits until the connection is closed:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第727行: 第569行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
  
  
第767行: 第609行:
  
  
asyncio.run(main())</pre>
+
asyncio.run(main())</syntaxhighlight>
  
 
</div>
 
</div>
第774行: 第616行:
 
<div class="admonition seealso">
 
<div class="admonition seealso">
  
参见
+
也可以看看
  
The [[../asyncio-stream#asyncio-tcp-echo-client-streams|<span class="std std-ref">TCP echo client using streams</span>]]
+
[[../asyncio-stream#asyncio-tcp-echo-client-streams|TCP 回显客户端使用流]] 示例使用高级 <code>asyncio.open_connection()</code> 函数。
example uses the high-level [[../asyncio-stream#asyncio|<code>asyncio.open_connection()</code>]] function.
 
  
  
第786行: 第627行:
  
 
<span id="asyncio-udp-echo-server-protocol"></span>
 
<span id="asyncio-udp-echo-server-protocol"></span>
=== UDP Echo Server ===
+
=== UDP 回波服务器 ===
  
A UDP echo server, using the [[../asyncio-eventloop#asyncio.loop|<code>loop.create_datagram_endpoint()</code>]]
+
UDP 回显服务器使用 <code>loop.create_datagram_endpoint()</code> 方法发回接收到的数据:
method, sends back received data:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第795行: 第635行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
  
  
第810行: 第650行:
  
 
async def main():
 
async def main():
     print(&quot;Starting UDP server&quot;)
+
     print("Starting UDP server")
  
 
     # Get a reference to the event loop as we plan to use
 
     # Get a reference to the event loop as we plan to use
第828行: 第668行:
  
  
asyncio.run(main())</pre>
+
asyncio.run(main())</syntaxhighlight>
  
 
</div>
 
</div>
第838行: 第678行:
  
 
<span id="asyncio-udp-echo-client-protocol"></span>
 
<span id="asyncio-udp-echo-client-protocol"></span>
=== UDP Echo Client ===
+
=== UDP 回声客户端 ===
  
A UDP echo client, using the [[../asyncio-eventloop#asyncio.loop|<code>loop.create_datagram_endpoint()</code>]]
+
UDP 回显客户端使用 <code>loop.create_datagram_endpoint()</code> 方法发送数据并在收到答复时关闭传输:
method, sends data and closes the transport when it receives the answer:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第847行: 第686行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
  
  
第862行: 第701行:
  
 
     def datagram_received(self, data, addr):
 
     def datagram_received(self, data, addr):
         print(&quot;Received:&quot;, data.decode())
+
         print("Received:", data.decode())
  
         print(&quot;Close the socket&quot;)
+
         print("Close the socket")
 
         self.transport.close()
 
         self.transport.close()
  
第871行: 第710行:
  
 
     def connection_lost(self, exc):
 
     def connection_lost(self, exc):
         print(&quot;Connection closed&quot;)
+
         print("Connection closed")
 
         self.on_con_lost.set_result(True)
 
         self.on_con_lost.set_result(True)
  
第881行: 第720行:
  
 
     on_con_lost = loop.create_future()
 
     on_con_lost = loop.create_future()
     message = &quot;Hello World!&quot;
+
     message = "Hello World!"
  
 
     transport, protocol = await loop.create_datagram_endpoint(
 
     transport, protocol = await loop.create_datagram_endpoint(
第893行: 第732行:
  
  
asyncio.run(main())</pre>
+
asyncio.run(main())</syntaxhighlight>
  
 
</div>
 
</div>
第903行: 第742行:
  
 
<span id="asyncio-example-create-connection"></span>
 
<span id="asyncio-example-create-connection"></span>
=== Connecting Existing Sockets ===
+
=== 连接现有的套接字 ===
  
Wait until a socket receives data using the
+
等待套接字使用带有协议的 <code>loop.create_connection()</code> 方法接收数据:
[[../asyncio-eventloop#asyncio.loop|<code>loop.create_connection()</code>]] method with a protocol:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第912行: 第750行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
 
import socket
 
import socket
  
第926行: 第764行:
  
 
     def data_received(self, data):
 
     def data_received(self, data):
         print(&quot;Received:&quot;, data.decode())
+
         print("Received:", data.decode())
  
 
         # We are done: close the transport;
 
         # We are done: close the transport;
第959行: 第797行:
 
         wsock.close()
 
         wsock.close()
  
asyncio.run(main())</pre>
+
asyncio.run(main())</syntaxhighlight>
  
 
</div>
 
</div>
第966行: 第804行:
 
<div class="admonition seealso">
 
<div class="admonition seealso">
  
参见
+
也可以看看
  
The [[../asyncio-eventloop#asyncio-example-watch-fd|<span class="std std-ref">watch a file descriptor for read events</span>]] example uses the low-level
+
[[../asyncio-eventloop#asyncio-example-watch-fd|watch a file descriptor for read events]] 示例使用低级 [[../asyncio-eventloop#asyncio.loop|loop.add_reader()]] 方法注册 FD。
[[../asyncio-eventloop#asyncio.loop|<code>loop.add_reader()</code>]] method to register an FD.
 
  
The [[../asyncio-stream#asyncio-example-create-connection-streams|<span class="std std-ref">register an open socket to wait for data using streams</span>]] example uses high-level streams
+
[[../asyncio-stream#asyncio-example-create-connection-streams|注册一个打开的套接字以使用流等待数据]] 示例使用由 <code>open_connection()</code> 函数在协程中创建的高级流。
created by the [[../asyncio-stream#asyncio|<code>open_connection()</code>]] function in a coroutine.
 
  
  
第981行: 第817行:
  
 
<span id="asyncio-example-subprocess-proto"></span>
 
<span id="asyncio-example-subprocess-proto"></span>
=== loop.subprocess_exec() and SubprocessProtocol ===
+
=== loop.subprocess_exec() SubprocessProtocol ===
  
An example of a subprocess protocol used to get the output of a
+
用于获取子进程输出并等待子进程退出的子进程协议示例。
subprocess and to wait for the subprocess exit.
 
  
The subprocess is created by the [[../asyncio-eventloop#asyncio.loop|<code>loop.subprocess_exec()</code>]] method:
+
子进程由 <code>loop.subprocess_exec()</code> 方法创建:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第992行: 第827行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
 
import sys
 
import sys
  
第1,034行: 第869行:
  
 
date = asyncio.run(get_date())
 
date = asyncio.run(get_date())
print(f&quot;Current date: {date}&quot;)</pre>
+
print(f"Current date: {date}")</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
See also the [[../asyncio-subprocess#asyncio-example-create-subprocess-exec|<span class="std std-ref">same example</span>]]
+
另请参阅使用高级 API 编写的 [[../asyncio-subprocess#asyncio-example-create-subprocess-exec|相同示例]]
written using high-level APIs.
+
 
  
 +
</div>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
 +
<div class="clearer">
 +
 +
  
 
</div>
 
</div>
  
[[Category:Python 3.9 中文文档]]
+
[[Category:Python 3.9 文档]]

2021年10月31日 (日) 04:51的最新版本

传输和协议

前言

传输和协议由 低级 事件循环 API 使用,例如 loop.create_connection()。 它们使用基于回调的编程风格并支持网络或 IPC 协议的高性能实现(例如 HTTP)。

本质上,传输和协议应该只在库和框架中使用,而不要在高级异步应用程序中使用。

本文档页面涵盖 传输协议

介绍

在最高级别,传输关注 如何 字节传输,而协议确定 传输哪些 字节(以及在某种程度上何时传输)。

说同一件事的另一种方式:从传输的角度来看,传输是套接字(或类似的 I/O 端点)的抽象,而协议是应用程序的抽象。

另一个观点是传输接口和协议接口一起定义了一个抽象接口,用于使用网络 I/O 和进程间 I/O。

传输和协议对象之间始终存在 1:1 的关系:协议调用传输方法发送数据,而传输调用协议方法将接收到的数据传递给它。

大多数面向连接的事件循环方法(例如 loop.create_connection())通常接受一个 protocol_factory 参数,用于为已接受的连接创建 Protocol 对象,由 表示]传输对象。 此类方法通常返回 (transport, protocol) 的元组。

内容

此文档页面包含以下部分:

运输

源代码: :source:`Lib/asyncio/transsports.py`



传输是 asyncio 提供的类,用于抽象各种通信通道。

传输对象总是由 异步事件循环 实例化。

asyncio 为 TCP、UDP、SSL 和子进程管道实现传输。 传输上可用的方法取决于传输的种类。

传输类 不是线程安全的

传输层次结构

class asyncio.BaseTransport
所有传输的基类。 包含所有 asyncio 传输共享的方法。
class asyncio.WriteTransport(BaseTransport)

只写连接的基本传输。

WriteTransport 类的实例从 loop.connect_write_pipe() 事件循环方法返回,并且也被子进程相关方法使用,如 loop.subprocess_exec()

class asyncio.ReadTransport(BaseTransport)

只读连接的基本传输。

ReadTransport 类的实例从 loop.connect_read_pipe() 事件循环方法返回,也被子进程相关方法使用,如 loop.subprocess_exec()

class asyncio.Transport(WriteTransport, ReadTransport)

表示双向传输的接口,例如 TCP 连接。

用户不直接实例化传输; 他们调用一个实用函数,将一个协议工厂和其他创建传输和协议所需的信息传递给它。

Transport 类的实例由 loop.create_connection()loop.create_unix_connection()loop.create_server()loop.sendfile() 等事件循环方法返回或使用.

class asyncio.DatagramTransport(BaseTransport)

数据报 (UDP) 连接的传输。

DatagramTransport 类的实例从 loop.create_datagram_endpoint() 事件循环方法返回。

class asyncio.SubprocessTransport(BaseTransport)

表示父操作系统与其子操作系统进程之间的连接的抽象。

SubprocessTransport 类的实例从事件循环方法 loop.subprocess_shell()loop.subprocess_exec() 返回。


基地运输

BaseTransport.close()

关闭运输。

如果传输具有用于传出数据的缓冲区,则将异步刷新缓冲数据。 将不再接收数据。 刷新所有缓冲数据后,将使用 None 作为参数调用协议的 protocol.connection_lost() 方法。

BaseTransport.is_closing()
如果传输正在关闭或已关闭,则返回 True
BaseTransport.get_extra_info(name, default=None)

返回有关它使用的传输或底层资源的信息。

name 是一个字符串,表示要获取的传输特定信息。

default 是在信息不可用时返回的值,或者如果传输不支持使用给定的第三方事件循环实现或在当前平台上查询它。

例如,以下代码尝试获取传输的底层套接字对象:

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

可以在某些传输上查询的信息类别:

BaseTransport.set_protocol(protocol)

设置新协议。

仅当两种协议都记录为支持切换时,才应执行切换协议。

BaseTransport.get_protocol()
返回当前协议。


只读传输

ReadTransport.is_reading()

如果传输正在接收新数据,则返回 True

3.7 版中的新功能。

ReadTransport.pause_reading()

暂停传输的接收端。 在调用 resume_reading() 之前,不会将数据传递给协议的 protocol.data_received() 方法。

3.7版本变化:方法是幂等的,即 当传输已经暂停或关闭时可以调用它。

ReadTransport.resume_reading()

恢复接收端。 如果某些数据可供读取,协议的 protocol.data_received() 方法将再次调用。

3.7版本变化:方法是幂等的,即 当传输已经读取时可以调用它。


只写传输

WriteTransport.abort()
立即关闭传输,无需等待挂起的操作完成。 缓冲的数据将丢失。 将不再接收数据。 协议的 protocol.connection_lost() 方法最终将使用 None 作为参数调用。
WriteTransport.can_write_eof()
如果传输支持 write_eof(),则返回 True,否则返回 False
WriteTransport.get_write_buffer_size()
返回传输使用的输出缓冲区的当前大小。
WriteTransport.get_write_buffer_limits()

获取 highlow 水印用于写流控制。 返回一个元组 (low, high),其中 lowhigh 是正字节数。

使用 set_write_buffer_limits() 设置限制。

版本 3.4.2 中的新功能。

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

设置highlow水印进行写流控制。

这两个值(以字节数衡量)控制何时调用协议的 protocol.pause_writing()protocol.resume_writing() 方法。 如果指定,低水印必须小于或等于高水印。 highlow 都不能为负数。

pause_writing() 当缓冲区大小变得大于或等于 high 值时调用。 如果写入已暂停,则在缓冲区大小小于或等于 low 值时调用 resume_writing()

默认值是特定于实现的。 如果仅给出高水印,则低水印默认为小于或等于高水印的特定于实现的值。 将 high 设置为零也会强制 low 为零,并导致每当缓冲区变为非空时调用 pause_writing()。 将 low 设置为零会导致 resume_writing() 仅在缓冲区为空时调用。 对任一限制使用零通常是次优的,因为它减少了同时进行 I/O 和计算的机会。

使用 get_write_buffer_limits() 获取限制。

WriteTransport.write(data)

将一些 data 字节写入传输。

这个方法不会阻塞; 它缓冲数据并安排它异步发送。

WriteTransport.writelines(list_of_data)
将数据字节的列表(或任何可迭代的)写入传输。 这在功能上等同于对迭代产生的每个元素调用 write(),但可以更有效地实现。
WriteTransport.write_eof()

刷新所有缓冲数据后关闭传输的写入端。 可能仍会收到数据。

如果传输(例如 SSL) 不支持半封闭连接。


数据报传输

DatagramTransport.sendto(data, addr=None)

data 字节发送到由 addr(依赖于传输的目标地址)给出的远程对等方。 如果 addrNone,则数据将发送到传输创建时给定的目标地址。

这个方法不会阻塞; 它缓冲数据并安排它异步发送。

DatagramTransport.abort()
立即关闭传输,无需等待挂起的操作完成。 缓冲的数据将丢失。 将不再接收数据。 协议的 protocol.connection_lost() 方法最终将使用 None 作为参数调用。


子流程传输

SubprocessTransport.get_pid()
以整数形式返回子进程进程 ID。
SubprocessTransport.get_pipe_transport(fd)
返回与整数文件描述符 fd 对应的通信管道的传输:
  • 0:标准输入的可读流传输 (stdin),或者 None 如果子进程不是用 stdin=PIPE 创建的
  • 1:标准输出的可写流传输 (stdout),或者 None 如果子进程不是用 stdout=PIPE 创建的
  • 2:标准错误的可写流传输 (stderr),或者 None 如果子进程不是用 stderr=PIPE 创建的
  • 其他 fd:
SubprocessTransport.get_returncode()
将子进程返回码作为整数返回,如果没有返回,则返回 None,类似于 subprocess.Popen.returncode 属性。
SubprocessTransport.kill()

杀死子进程。

在 POSIX 系统上,该函数将 SIGKILL 发送到子进程。 在 Windows 上,此方法是 terminate() 的别名。

另见 subprocess.Popen.kill()

SubprocessTransport.send_signal(signal)
信号 编号发送到子进程,如 subprocess.Popen.send_signal()
SubprocessTransport.terminate()

停止子进程。

在 POSIX 系统上,此方法将 SIGTERM 发送到子进程。 在 Windows 上,调用 Windows API 函数 TerminateProcess() 来停止子进程。

另见 subprocess.Popen.terminate()

SubprocessTransport.close()

通过调用 kill() 方法终止子进程。

如果子进程尚未返回,则关闭 stdinstdoutstderr 管道的传输。


协议

源代码: :source:`Lib/asyncio/protocols.py`



asyncio 提供了一组用于实现网络协议的抽象基类。 这些类旨在与 传输 一起使用。

抽象基协议类的子类可以实现一些或所有方法。 所有这些方法都是回调:它们在某些事件上被传输调用,例如当接收到一些数据时。 相应的传输应调用基本协议方法。

基本协议

class asyncio.BaseProtocol
具有所有协议共享的方法的基本协议。
class asyncio.Protocol(BaseProtocol)
用于实现流协议(TCP、Unix 套接字等)的基类。
class asyncio.BufferedProtocol(BaseProtocol)
用于通过手动控制接收缓冲区来实现流协议的基类。
class asyncio.DatagramProtocol(BaseProtocol)
用于实现数据报 (UDP) 协议的基类。
class asyncio.SubprocessProtocol(BaseProtocol)
用于实现与子进程(单向管道)通信的协议的基类。


基础协议

所有 asyncio 协议都可以实现 Base Protocol 回调。

连接回调

对所有协议调用连接回调,每次成功连接仅调用一次。 所有其他协议回调只能在这两种方法之间调用。

BaseProtocol.connection_made(transport)

建立连接时调用。

transport 参数是表示连接的传输。 该协议负责存储对其传输的引用。

BaseProtocol.connection_lost(exc)

当连接丢失或关闭时调用。

参数是异常对象或 None。 后者意味着接收到常规 EOF,或者连接被连接的这一侧中止或关闭。

流控制回调

传输可以调用流控制回调来暂停或恢复协议执行的写入。

有关更多详细信息,请参阅 set_write_buffer_limits() 方法的文档。

BaseProtocol.pause_writing()
当传输的缓冲区超过高水位线时调用。
BaseProtocol.resume_writing()
当传输的缓冲区耗尽低于低水位线时调用。

如果缓冲区大小等于高水印,则不调用 pause_writing():缓冲区大小必须严格超过。

相反,当缓冲区大小等于或小于低水印时,会调用 resume_writing()。 当任一标记为零时,这些结束条件对于确保事情按预期进行非常重要。


流媒体协议

事件方法,例如 loop.create_server()loop.create_unix_server()loop.create_connection()loop.create_unix_connection()loop.connect_accepted_socket()loop.connect_read_pipe()loop.connect_write_pipe() 接受返回流协议的工厂。

Protocol.data_received(data)

当接收到一些数据时调用。 data 是一个包含传入数据的非空字节对象。

数据是缓冲、分块还是重组取决于传输。 通常,您不应依赖特定的语义,而应使解析通用且灵活。 但是,数据总是以正确的顺序接收。

该方法可以在连接打开时调用任意次数。

然而, protocol.eof_received() 最多被调用一次。 一旦 eof_received() 被调用,data_received() 就不再被调用。

Protocol.eof_received()

当另一端发出信号不会再发送任何数据时调用(例如通过调用 transport.write_eof(),如果另一端也使用 asyncio)。

此方法可能会返回一个错误值(包括 None),在这种情况下传输将自行关闭。 相反,如果此方法返回真值,则使用的协议确定是否关闭传输。 由于默认实现返回 None,它隐式关闭连接。

某些传输(包括 SSL)不支持半关闭连接,在这种情况下,从此方法返回 true 将导致连接被关闭。

状态机:

start -> connection_made
    [-> data_received]*
    [-> eof_received]?
-> connection_lost -> end

缓冲流协议

3.7 版中的新功能。


缓冲协议可以与任何支持 流协议 的事件循环方法一起使用。

BufferedProtocol 实现允许显式手动分配和控制接收缓冲区。 然后事件循环可以使用协议提供的缓冲区来避免不必要的数据复制。 这可以显着提高接收大量数据的协议的性能。 复杂的协议实现可以显着减少缓冲区分配的数量。

BufferedProtocol 实例上调用以下回调:

BufferedProtocol.get_buffer(sizehint)

调用以分配新的接收缓冲区。

sizehint 是推荐的返回缓冲区的最小大小。 返回比 sizehint 建议的更小或更大的缓冲区是可以接受的。 当设置为 -1 时,缓冲区大小可以是任意的。 返回大小为零的缓冲区是错误的。

get_buffer() 必须返回一个实现 缓冲协议 的对象。

BufferedProtocol.buffer_updated(nbytes)

在使用接收到的数据更新缓冲区时调用。

nbytes 是写入缓冲区的总字节数。

BufferedProtocol.eof_received()
请参阅 protocol.eof_received() 方法的文档。

get_buffer() 在连接期间可以被调用任意次数。 然而, protocol.eof_received() 最多被调用一次,如果被调用,get_buffer()buffer_updated() 将不会被调用。

状态机:

start -> connection_made
    [-> get_buffer
        [-> buffer_updated]?
    ]*
    [-> eof_received]?
-> connection_lost -> end

数据报协议

数据报协议实例应该由传递给 loop.create_datagram_endpoint() 方法的协议工厂构造。

DatagramProtocol.datagram_received(data, addr)
收到数据报时调用。 data 是一个包含传入数据的字节对象。 addr为发送数据的peer地址; 确切的格式取决于传输。
DatagramProtocol.error_received(exc)

当先前的发送或接收操作引发 OSError 时调用。 excOSError 实例。

在极少数情况下调用此方法,当传输(例如 UDP) 检测到数据报无法传送到其接收者。 但在许多情况下,无法传递的数据报将被悄悄丢弃。

笔记

在 BSD 系统(macOS、FreeBSD 等)上,数据报协议不支持流量控制,因为没有可靠的方法来检测由于写入过多数据包而导致的发送失败。

套接字始终显示为“就绪”,多余的数据包将被丢弃。 OSError errno 设置为 errno.ENOBUFS 可能会也可能不会引发; 如果它被引发,它将被报告给 DatagramProtocol.error_received() 但否则会被忽略。


子进程协议

子进程协议实例应该由传递给 loop.subprocess_exec()loop.subprocess_shell() 方法的协议工厂构造。

SubprocessProtocol.pipe_data_received(fd, data)

当子进程将数据写入其 stdout 或 stderr 管道时调用。

fd 是管道的整数文件描述符。

data 是一个包含接收数据的非空字节对象。

SubprocessProtocol.pipe_connection_lost(fd, exc)

当与子进程通信的管道之一关闭时调用。

fd 是已关闭的整数文件描述符。

SubprocessProtocol.process_exited()
当子进程退出时调用。


例子

TCP 回声服务器

使用 loop.create_server() 方法创建一个 TCP 回显服务器,发送回接收到的数据,并关闭连接:

import asyncio


class EchoServerProtocol(asyncio.Protocol):
    def connection_made(self, transport):
        peername = transport.get_extra_info('peername')
        print('Connection from {}'.format(peername))
        self.transport = transport

    def data_received(self, data):
        message = data.decode()
        print('Data received: {!r}'.format(message))

        print('Send: {!r}'.format(message))
        self.transport.write(data)

        print('Close the client socket')
        self.transport.close()


async def main():
    # Get a reference to the event loop as we plan to use
    # low-level APIs.
    loop = asyncio.get_running_loop()

    server = await loop.create_server(
        lambda: EchoServerProtocol(),
        '127.0.0.1', 8888)

    async with server:
        await server.serve_forever()


asyncio.run(main())

也可以看看

TCP 回显服务器使用流 示例使用高级 asyncio.start_server() 函数。


TCP 回显客户端

使用 loop.create_connection() 方法的 TCP 回显客户端发送数据,并等待连接关闭:

import asyncio


class EchoClientProtocol(asyncio.Protocol):
    def __init__(self, message, on_con_lost):
        self.message = message
        self.on_con_lost = on_con_lost

    def connection_made(self, transport):
        transport.write(self.message.encode())
        print('Data sent: {!r}'.format(self.message))

    def data_received(self, data):
        print('Data received: {!r}'.format(data.decode()))

    def connection_lost(self, exc):
        print('The server closed the connection')
        self.on_con_lost.set_result(True)


async def main():
    # Get a reference to the event loop as we plan to use
    # low-level APIs.
    loop = asyncio.get_running_loop()

    on_con_lost = loop.create_future()
    message = 'Hello World!'

    transport, protocol = await loop.create_connection(
        lambda: EchoClientProtocol(message, on_con_lost),
        '127.0.0.1', 8888)

    # Wait until the protocol signals that the connection
    # is lost and close the transport.
    try:
        await on_con_lost
    finally:
        transport.close()


asyncio.run(main())

也可以看看

TCP 回显客户端使用流 示例使用高级 asyncio.open_connection() 函数。


UDP 回波服务器

UDP 回显服务器使用 loop.create_datagram_endpoint() 方法发回接收到的数据:

import asyncio


class EchoServerProtocol:
    def connection_made(self, transport):
        self.transport = transport

    def datagram_received(self, data, addr):
        message = data.decode()
        print('Received %r from %s' % (message, addr))
        print('Send %r to %s' % (message, addr))
        self.transport.sendto(data, addr)


async def main():
    print("Starting UDP server")

    # Get a reference to the event loop as we plan to use
    # low-level APIs.
    loop = asyncio.get_running_loop()

    # One protocol instance will be created to serve all
    # client requests.
    transport, protocol = await loop.create_datagram_endpoint(
        lambda: EchoServerProtocol(),
        local_addr=('127.0.0.1', 9999))

    try:
        await asyncio.sleep(3600)  # Serve for 1 hour.
    finally:
        transport.close()


asyncio.run(main())

UDP 回声客户端

UDP 回显客户端使用 loop.create_datagram_endpoint() 方法发送数据并在收到答复时关闭传输:

import asyncio


class EchoClientProtocol:
    def __init__(self, message, on_con_lost):
        self.message = message
        self.on_con_lost = on_con_lost
        self.transport = None

    def connection_made(self, transport):
        self.transport = transport
        print('Send:', self.message)
        self.transport.sendto(self.message.encode())

    def datagram_received(self, data, addr):
        print("Received:", data.decode())

        print("Close the socket")
        self.transport.close()

    def error_received(self, exc):
        print('Error received:', exc)

    def connection_lost(self, exc):
        print("Connection closed")
        self.on_con_lost.set_result(True)


async def main():
    # Get a reference to the event loop as we plan to use
    # low-level APIs.
    loop = asyncio.get_running_loop()

    on_con_lost = loop.create_future()
    message = "Hello World!"

    transport, protocol = await loop.create_datagram_endpoint(
        lambda: EchoClientProtocol(message, on_con_lost),
        remote_addr=('127.0.0.1', 9999))

    try:
        await on_con_lost
    finally:
        transport.close()


asyncio.run(main())

连接现有的套接字

等待套接字使用带有协议的 loop.create_connection() 方法接收数据:

import asyncio
import socket


class MyProtocol(asyncio.Protocol):

    def __init__(self, on_con_lost):
        self.transport = None
        self.on_con_lost = on_con_lost

    def connection_made(self, transport):
        self.transport = transport

    def data_received(self, data):
        print("Received:", data.decode())

        # We are done: close the transport;
        # connection_lost() will be called automatically.
        self.transport.close()

    def connection_lost(self, exc):
        # The socket has been closed
        self.on_con_lost.set_result(True)


async def main():
    # Get a reference to the event loop as we plan to use
    # low-level APIs.
    loop = asyncio.get_running_loop()
    on_con_lost = loop.create_future()

    # Create a pair of connected sockets
    rsock, wsock = socket.socketpair()

    # Register the socket to wait for data.
    transport, protocol = await loop.create_connection(
        lambda: MyProtocol(on_con_lost), sock=rsock)

    # Simulate the reception of data from the network.
    loop.call_soon(wsock.send, 'abc'.encode())

    try:
        await protocol.on_con_lost
    finally:
        transport.close()
        wsock.close()

asyncio.run(main())

也可以看看

watch a file descriptor for read events 示例使用低级 loop.add_reader() 方法注册 FD。

注册一个打开的套接字以使用流等待数据 示例使用由 open_connection() 函数在协程中创建的高级流。


loop.subprocess_exec() 和 SubprocessProtocol

用于获取子进程输出并等待子进程退出的子进程协议示例。

子进程由 loop.subprocess_exec() 方法创建:

import asyncio
import sys

class DateProtocol(asyncio.SubprocessProtocol):
    def __init__(self, exit_future):
        self.exit_future = exit_future
        self.output = bytearray()

    def pipe_data_received(self, fd, data):
        self.output.extend(data)

    def process_exited(self):
        self.exit_future.set_result(True)

async def get_date():
    # Get a reference to the event loop as we plan to use
    # low-level APIs.
    loop = asyncio.get_running_loop()

    code = 'import datetime; print(datetime.datetime.now())'
    exit_future = asyncio.Future(loop=loop)

    # Create the subprocess controlled by DateProtocol;
    # redirect the standard output into a pipe.
    transport, protocol = await loop.subprocess_exec(
        lambda: DateProtocol(exit_future),
        sys.executable, '-c', code,
        stdin=None, stderr=None)

    # Wait for the subprocess exit using the process_exited()
    # method of the protocol.
    await exit_future

    # Close the stdout pipe.
    transport.close()

    # Read the output which was collected by the
    # pipe_data_received() method of the protocol.
    data = bytes(protocol.output)
    return data.decode('ascii').rstrip()

date = asyncio.run(get_date())
print(f"Current date: {date}")

另请参阅使用高级 API 编写的 相同示例