Files
hustoj/web/python-docs/library/asyncio-protocol.html
2025-03-09 17:10:56 +08:00

1133 lines
109 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>传输和协议 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="策略" href="asyncio-policy.html" />
<link rel="prev" title="Futures" href="asyncio-future.html" />
<link rel="canonical" href="https://docs.python.org/3/library/asyncio-protocol.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">传输和协议</a><ul>
<li><a class="reference internal" href="#transports">传输</a><ul>
<li><a class="reference internal" href="#transports-hierarchy">传输层级</a></li>
<li><a class="reference internal" href="#base-transport">基础传输</a></li>
<li><a class="reference internal" href="#read-only-transports">只读传输</a></li>
<li><a class="reference internal" href="#write-only-transports">只写传输</a></li>
<li><a class="reference internal" href="#datagram-transports">数据报传输</a></li>
<li><a class="reference internal" href="#subprocess-transports">子进程传输</a></li>
</ul>
</li>
<li><a class="reference internal" href="#protocols">协议</a><ul>
<li><a class="reference internal" href="#base-protocols">基础协议</a></li>
<li><a class="reference internal" href="#base-protocol">基础协议</a></li>
<li><a class="reference internal" href="#streaming-protocols">流协议</a></li>
<li><a class="reference internal" href="#buffered-streaming-protocols">缓冲流协议</a></li>
<li><a class="reference internal" href="#datagram-protocols">数据报协议</a></li>
<li><a class="reference internal" href="#subprocess-protocols">子进程协议</a></li>
</ul>
</li>
<li><a class="reference internal" href="#examples">例子</a><ul>
<li><a class="reference internal" href="#tcp-echo-server">TCP回应服务器</a></li>
<li><a class="reference internal" href="#tcp-echo-client">TCP回应客户端</a></li>
<li><a class="reference internal" href="#udp-echo-server">UDP回应服务器</a></li>
<li><a class="reference internal" href="#udp-echo-client">UDP回应客户端</a></li>
<li><a class="reference internal" href="#connecting-existing-sockets">链接已存在的套接字</a></li>
<li><a class="reference internal" href="#loop-subprocess-exec-and-subprocessprotocol">loop.subprocess_exec() 与 SubprocessProtocol</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="asyncio-future.html"
title="上一章">Futures</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="asyncio-policy.html"
title="下一章">策略</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/library/asyncio-protocol.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/library/asyncio-protocol.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="asyncio-policy.html" title="策略"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="asyncio-future.html" title="Futures"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="ipc.html" >网络和进程间通信</a> &#187;</li>
<li class="nav-item nav-item-3"><a href="asyncio.html" accesskey="U"><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> --- 异步 I/O</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="transports-and-protocols">
<span id="asyncio-transports-protocols"></span><h1>传输和协议<a class="headerlink" href="#transports-and-protocols" title="永久链接至标题"></a></h1>
<p class="rubric">前言</p>
<p>传输和协议会被像 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a> 这类 <strong>底层</strong> 事件循环接口使用。它们使用基于回调的编程风格支持网络或IPC协议如HTTP的高性能实现。</p>
<p>基本上,传输和协议应只在库和框架上使用,而不应该在高层的异步应用中使用它们。</p>
<p>本文档包含 <a class="reference internal" href="#transports">Transports</a><a class="reference internal" href="#protocols">Protocols</a></p>
<p class="rubric">概述</p>
<p>在最顶层,传输只关心 <strong>怎样</strong> 传送字节内容,而协议决定传送 <strong>哪些</strong> 字节内容(还要在一定程度上考虑何时)。</p>
<p>也可以这样说:从传输的角度来看,传输是套接字(或类似的I/O终端)的抽象,而协议是应用程序的抽象。</p>
<p>换另一种说法传输和协议一起定义网络I/0和进程间I/O的抽象接口。</p>
<p>传输对象和协议对象总是一对一关系:协议调用传输方法来发送数据,而传输在接收到数据时调用协议方法传递数据。</p>
<p>大部分面向连接的事件循环方法(如 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a> ) 通常接受 <em>protocol_factory</em> 参数为接收到的链接创建 <em>协议</em> 对象,并用 <em>传输</em> 对象来表示。这些方法一般会返回 <code class="docutils literal notranslate"><span class="pre">(transport,</span> <span class="pre">protocol)</span></code> 元组。</p>
<p class="rubric">目录</p>
<p>本文档包含下列小节:</p>
<ul class="simple">
<li><p><a class="reference internal" href="#transports">传输</a> 部分记载异步IO <a class="reference internal" href="#asyncio.BaseTransport" title="asyncio.BaseTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseTransport</span></code></a><a class="reference internal" href="#asyncio.ReadTransport" title="asyncio.ReadTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">ReadTransport</span></code></a><a class="reference internal" href="#asyncio.WriteTransport" title="asyncio.WriteTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">WriteTransport</span></code></a><a class="reference internal" href="#asyncio.Transport" title="asyncio.Transport"><code class="xref py py-class docutils literal notranslate"><span class="pre">Transport</span></code></a><a class="reference internal" href="#asyncio.DatagramTransport" title="asyncio.DatagramTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">DatagramTransport</span></code></a><a class="reference internal" href="#asyncio.SubprocessTransport" title="asyncio.SubprocessTransport"><code class="xref py py-class docutils literal notranslate"><span class="pre">SubprocessTransport</span></code></a> 等类。</p></li>
<li><p>The <a class="reference internal" href="#protocols">Protocols</a> section documents asyncio <a class="reference internal" href="#asyncio.BaseProtocol" title="asyncio.BaseProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseProtocol</span></code></a>,
<a class="reference internal" href="#asyncio.Protocol" title="asyncio.Protocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">Protocol</span></code></a>, <a class="reference internal" href="#asyncio.BufferedProtocol" title="asyncio.BufferedProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">BufferedProtocol</span></code></a>,
<a class="reference internal" href="#asyncio.DatagramProtocol" title="asyncio.DatagramProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">DatagramProtocol</span></code></a>, and <a class="reference internal" href="#asyncio.SubprocessProtocol" title="asyncio.SubprocessProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">SubprocessProtocol</span></code></a> classes.</p></li>
<li><p><a class="reference internal" href="#examples">例子</a> 部分展示怎样使用传输、协议和底层事件循环接口。</p></li>
</ul>
<section id="transports">
<span id="asyncio-transport"></span><h2>传输<a class="headerlink" href="#transports" title="永久链接至标题"></a></h2>
<p><strong>源码:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.8/Lib/asyncio/transports.py">Lib/asyncio/transports.py</a></p>
<hr class="docutils" />
<p>传输属于 <a class="reference internal" href="asyncio.html#module-asyncio" title="asyncio: Asynchronous I/O."><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code></a> 模块中的类,用来抽象各种通信通道。</p>
<p>传输对象总是由 <a class="reference internal" href="asyncio-eventloop.html#asyncio-event-loop"><span class="std std-ref">异步IO事件循环</span></a> 实例化。</p>
<p>异步IO实现TCP、UDP、SSL和子进程管道的传输。传输上可用的方法由传输的类型决定。</p>
<p>传输类属于 <a class="reference internal" href="asyncio-dev.html#asyncio-multithreading"><span class="std std-ref">线程不安全</span></a></p>
<section id="transports-hierarchy">
<h3>传输层级<a class="headerlink" href="#transports-hierarchy" title="永久链接至标题"></a></h3>
<dl class="class">
<dt id="asyncio.BaseTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">BaseTransport</code><a class="headerlink" href="#asyncio.BaseTransport" title="永久链接至目标"></a></dt>
<dd><p>所有传输的基类。包含所有异步IO传输共用的方法。</p>
</dd></dl>
<dl class="class">
<dt id="asyncio.WriteTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">WriteTransport</code><span class="sig-paren">(</span><em class="sig-param">BaseTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport" title="永久链接至目标"></a></dt>
<dd><p>只写链接的基础传输。</p>
<p>Instances of the <em>WriteTransport</em> class are returned from
the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_write_pipe" title="asyncio.loop.connect_write_pipe"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_write_pipe()</span></code></a> event loop method and
are also used by subprocess-related methods like
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a>.</p>
</dd></dl>
<dl class="class">
<dt id="asyncio.ReadTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">ReadTransport</code><span class="sig-paren">(</span><em class="sig-param">BaseTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.ReadTransport" title="永久链接至目标"></a></dt>
<dd><p>只读链接的基础传输。</p>
<p>Instances of the <em>ReadTransport</em> class are returned from
the <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_read_pipe" title="asyncio.loop.connect_read_pipe"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_read_pipe()</span></code></a> event loop method and
are also used by subprocess-related methods like
<a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a>.</p>
</dd></dl>
<dl class="class">
<dt id="asyncio.Transport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">Transport</code><span class="sig-paren">(</span><em class="sig-param">WriteTransport</em>, <em class="sig-param">ReadTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Transport" title="永久链接至目标"></a></dt>
<dd><p>接口代表一个双向传输如TCP链接。</p>
<p>用户不用直接实例化传输;调用一个功能函数,给它传递协议工厂和其它需要的信息就可以创建传输和协议。</p>
<p><em>传输</em> 类实例由如 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a><a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_unix_connection" title="asyncio.loop.create_unix_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_unix_connection()</span></code></a><a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_server" title="asyncio.loop.create_server"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_server()</span></code></a><a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.sendfile" title="asyncio.loop.sendfile"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.sendfile()</span></code></a> 等这类事件循环方法使用或返回。</p>
</dd></dl>
<dl class="class">
<dt id="asyncio.DatagramTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">DatagramTransport</code><span class="sig-paren">(</span><em class="sig-param">BaseTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramTransport" title="永久链接至目标"></a></dt>
<dd><p>数据报(UDP)传输链接。</p>
<p><em>DatagramTransport</em> 类实例由事件循环方法 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_datagram_endpoint" title="asyncio.loop.create_datagram_endpoint"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_datagram_endpoint()</span></code></a> 返回。</p>
</dd></dl>
<dl class="class">
<dt id="asyncio.SubprocessTransport">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">SubprocessTransport</code><span class="sig-paren">(</span><em class="sig-param">BaseTransport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport" title="永久链接至目标"></a></dt>
<dd><p>表示父进程和子进程之间连接的抽象。</p>
<p><em>SubprocessTransport</em> 类的实例由事件循环方法 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_shell" title="asyncio.loop.subprocess_shell"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_shell()</span></code></a><a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a> 返回。</p>
</dd></dl>
</section>
<section id="base-transport">
<h3>基础传输<a class="headerlink" href="#base-transport" title="永久链接至标题"></a></h3>
<dl class="method">
<dt id="asyncio.BaseTransport.close">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.close" title="永久链接至目标"></a></dt>
<dd><p>关闭传输。</p>
<p>如果传输具有发送数据缓冲区,将会异步发送已缓存的数据。在所有已缓存的数据都已处理后,就会将 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 作为协议 <a class="reference internal" href="#asyncio.BaseProtocol.connection_lost" title="asyncio.BaseProtocol.connection_lost"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.connection_lost()</span></code></a> 方法的参数并进行调用。在这之后,传输不再接收任何数据。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.BaseTransport.is_closing">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">is_closing</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.is_closing" title="永久链接至目标"></a></dt>
<dd><p>返回 <code class="docutils literal notranslate"><span class="pre">True</span></code> ,如果传输正在关闭或已经关闭。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.BaseTransport.get_extra_info">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">get_extra_info</code><span class="sig-paren">(</span><em class="sig-param">name</em>, <em class="sig-param">default=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.get_extra_info" title="永久链接至目标"></a></dt>
<dd><p>返回 传输或它使用的相关资源信息。</p>
<p><em>name</em> 是表示要获取传输特定信息的字符串。</p>
<p><em>default</em> 是在信息不可用或传输不支持第三方事件循环实现或当前平台查询时返回的值。</p>
<p>例如下面代码尝试获取传输相关套接字对象:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">sock</span> <span class="o">=</span> <span class="n">transport</span><span class="o">.</span><span class="n">get_extra_info</span><span class="p">(</span><span class="s1">&#39;socket&#39;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">sock</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sock</span><span class="o">.</span><span class="n">getsockopt</span><span class="p">(</span><span class="o">...</span><span class="p">))</span>
</pre></div>
</div>
<p>传输可查询信息类别:</p>
<ul class="simple">
<li><p>套接字:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">'peername'</span></code>: 套接字链接时的远端地址,<a class="reference internal" href="socket.html#socket.socket.getpeername" title="socket.socket.getpeername"><code class="xref py py-meth docutils literal notranslate"><span class="pre">socket.socket.getpeername()</span></code></a> 方法的结果 (出错时为 <code class="docutils literal notranslate"><span class="pre">None</span></code> )</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'socket'</span></code>: <a class="reference internal" href="socket.html#socket.socket" title="socket.socket"><code class="xref py py-class docutils literal notranslate"><span class="pre">socket.socket</span></code></a> 实例</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'sockname'</span></code>: 套接字本地地址, <a class="reference internal" href="socket.html#socket.socket.getsockname" title="socket.socket.getsockname"><code class="xref py py-meth docutils literal notranslate"><span class="pre">socket.socket.getsockname()</span></code></a> 方法的结果</p></li>
</ul>
</li>
<li><p>SSL套接字</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">'compression'</span></code>: 用字符串指定压缩算法,或者链接没有压缩时为 <code class="docutils literal notranslate"><span class="pre">None</span></code> <a class="reference internal" href="ssl.html#ssl.SSLSocket.compression" title="ssl.SSLSocket.compression"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ssl.SSLSocket.compression()</span></code></a> 的结果。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'cipher'</span></code>: 一个三值的元组包含使用密码的名称定义使用的SSL协议的版本使用的加密位数。 <a class="reference internal" href="ssl.html#ssl.SSLSocket.cipher" title="ssl.SSLSocket.cipher"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ssl.SSLSocket.cipher()</span></code></a> 的结果。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'peercert'</span></code>: 远端凭证; <a class="reference internal" href="ssl.html#ssl.SSLSocket.getpeercert" title="ssl.SSLSocket.getpeercert"><code class="xref py py-meth docutils literal notranslate"><span class="pre">ssl.SSLSocket.getpeercert()</span></code></a> 结果。</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'sslcontext'</span></code>: <a class="reference internal" href="ssl.html#ssl.SSLContext" title="ssl.SSLContext"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLContext</span></code></a> 实例</p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">'ssl_object'</span></code>: <a class="reference internal" href="ssl.html#ssl.SSLObject" title="ssl.SSLObject"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLObject</span></code></a><a class="reference internal" href="ssl.html#ssl.SSLSocket" title="ssl.SSLSocket"><code class="xref py py-class docutils literal notranslate"><span class="pre">ssl.SSLSocket</span></code></a> 实例</p></li>
</ul>
</li>
<li><p>管道:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">'pipe'</span></code>: 管道对象</p></li>
</ul>
</li>
<li><p>子进程:</p>
<ul>
<li><p><code class="docutils literal notranslate"><span class="pre">'subprocess'</span></code>: <a class="reference internal" href="subprocess.html#subprocess.Popen" title="subprocess.Popen"><code class="xref py py-class docutils literal notranslate"><span class="pre">subprocess.Popen</span></code></a> 实例</p></li>
</ul>
</li>
</ul>
</dd></dl>
<dl class="method">
<dt id="asyncio.BaseTransport.set_protocol">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">set_protocol</code><span class="sig-paren">(</span><em class="sig-param">protocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.set_protocol" title="永久链接至目标"></a></dt>
<dd><p>设置一个新协议。</p>
<p>只有两种协议都写明支持切换才能完成切换协议。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.BaseTransport.get_protocol">
<code class="sig-prename descclassname">BaseTransport.</code><code class="sig-name descname">get_protocol</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseTransport.get_protocol" title="永久链接至目标"></a></dt>
<dd><p>返回当前协议。</p>
</dd></dl>
</section>
<section id="read-only-transports">
<h3>只读传输<a class="headerlink" href="#read-only-transports" title="永久链接至标题"></a></h3>
<dl class="method">
<dt id="asyncio.ReadTransport.is_reading">
<code class="sig-prename descclassname">ReadTransport.</code><code class="sig-name descname">is_reading</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.ReadTransport.is_reading" title="永久链接至目标"></a></dt>
<dd><p>如果传输接收到新数据时返回 <code class="docutils literal notranslate"><span class="pre">True</span></code></p>
<div class="versionadded">
<p><span class="versionmodified added">3.7 新版功能.</span></p>
</div>
</dd></dl>
<dl class="method">
<dt id="asyncio.ReadTransport.pause_reading">
<code class="sig-prename descclassname">ReadTransport.</code><code class="sig-name descname">pause_reading</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.ReadTransport.pause_reading" title="永久链接至目标"></a></dt>
<dd><p>暂停传输的接收端。<a class="reference internal" href="#asyncio.Protocol.data_received" title="asyncio.Protocol.data_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.data_received()</span></code></a> 方法将不会收到数据,除非 <a class="reference internal" href="#asyncio.ReadTransport.resume_reading" title="asyncio.ReadTransport.resume_reading"><code class="xref py py-meth docutils literal notranslate"><span class="pre">resume_reading()</span></code></a>  被调用。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>这个方法幂等的, 它可以在传输已经暂停或关闭时调用。</p>
</div>
</dd></dl>
<dl class="method">
<dt id="asyncio.ReadTransport.resume_reading">
<code class="sig-prename descclassname">ReadTransport.</code><code class="sig-name descname">resume_reading</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.ReadTransport.resume_reading" title="永久链接至目标"></a></dt>
<dd><p>恢复接收端。如果有数据可读取时,协议方法 <a class="reference internal" href="#asyncio.Protocol.data_received" title="asyncio.Protocol.data_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.data_received()</span></code></a> 将再次被调用。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>这个方法幂等的, 它可以在传输已经准备好读取数据时调用。</p>
</div>
</dd></dl>
</section>
<section id="write-only-transports">
<h3>只写传输<a class="headerlink" href="#write-only-transports" title="永久链接至标题"></a></h3>
<dl class="method">
<dt id="asyncio.WriteTransport.abort">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">abort</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.abort" title="永久链接至目标"></a></dt>
<dd><p>立即关闭传输,不会等待已提交的操作处理完毕。已缓存的数据将会丢失。不会接收更多数据。 最终 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 将作为协议的 <a class="reference internal" href="#asyncio.BaseProtocol.connection_lost" title="asyncio.BaseProtocol.connection_lost"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.connection_lost()</span></code></a> 方法的参数被调用。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.WriteTransport.can_write_eof">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">can_write_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.can_write_eof" title="永久链接至目标"></a></dt>
<dd><p>如果传输支持 <a class="reference internal" href="#asyncio.WriteTransport.write_eof" title="asyncio.WriteTransport.write_eof"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write_eof()</span></code></a> 返回 <a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal notranslate"><span class="pre">True</span></code></a> 否则返回 <a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal notranslate"><span class="pre">False</span></code></a></p>
</dd></dl>
<dl class="method">
<dt id="asyncio.WriteTransport.get_write_buffer_size">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">get_write_buffer_size</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.get_write_buffer_size" title="永久链接至目标"></a></dt>
<dd><p>返回传输使用输出缓冲区的当前大小。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.WriteTransport.get_write_buffer_limits">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">get_write_buffer_limits</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.get_write_buffer_limits" title="永久链接至目标"></a></dt>
<dd><p>获取写入流控制 <em>high</em><em>low</em> 高低标记位。返回元组 <code class="docutils literal notranslate"><span class="pre">(low,</span> <span class="pre">high)</span></code> <em>low</em><em>high</em> 为正字节数。</p>
<p>使用 <a class="reference internal" href="#asyncio.WriteTransport.set_write_buffer_limits" title="asyncio.WriteTransport.set_write_buffer_limits"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_write_buffer_limits()</span></code></a> 设置限制。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.4.2 新版功能.</span></p>
</div>
</dd></dl>
<dl class="method">
<dt id="asyncio.WriteTransport.set_write_buffer_limits">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">set_write_buffer_limits</code><span class="sig-paren">(</span><em class="sig-param">high=None</em>, <em class="sig-param">low=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.set_write_buffer_limits" title="永久链接至目标"></a></dt>
<dd><p>设置写入流控制 <em>high</em><em>low</em> 高低标记位。</p>
<p>这两个值(以字节数表示)控制何时调用协议的 <a class="reference internal" href="#asyncio.BaseProtocol.pause_writing" title="asyncio.BaseProtocol.pause_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.pause_writing()</span></code></a><a class="reference internal" href="#asyncio.BaseProtocol.resume_writing" title="asyncio.BaseProtocol.resume_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.resume_writing()</span></code></a> 方法。 如果指明,则低水位必须小于或等于高水位。 <em>high</em><em>low</em> 都不能为负值。</p>
<p><a class="reference internal" href="#asyncio.BaseProtocol.pause_writing" title="asyncio.BaseProtocol.pause_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">pause_writing()</span></code></a> 会在缓冲区尺寸大于或等于 <em>high</em> 值时被调用。 如果写入已经被暂停,<a class="reference internal" href="#asyncio.BaseProtocol.resume_writing" title="asyncio.BaseProtocol.resume_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">resume_writing()</span></code></a> 会在缓冲区尺寸小于或等于 <em>low</em> 值时被调用。</p>
<p>默认值是实现专属的。 如果只给出了高水位值,则低水位值默认为一个小于或等于高水位值的实现传属值。 将 <em>high</em> 设为零会强制将 <em>low</em> 也设为零,并使得 <a class="reference internal" href="#asyncio.BaseProtocol.pause_writing" title="asyncio.BaseProtocol.pause_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">pause_writing()</span></code></a> 在缓冲区变为非空的任何时刻被调用。 将 <em>low</em> 设为零会使得 <a class="reference internal" href="#asyncio.BaseProtocol.resume_writing" title="asyncio.BaseProtocol.resume_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">resume_writing()</span></code></a> 在缓冲区为空时只被调用一次。 对于上下限都使用零值通常是不够优化的,因为它减少了并发执行 I/O 和计算的机会。</p>
<p>可使用 <a class="reference internal" href="#asyncio.WriteTransport.get_write_buffer_limits" title="asyncio.WriteTransport.get_write_buffer_limits"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_write_buffer_limits()</span></code></a> 来获取上下限值。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.WriteTransport.write">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">write</code><span class="sig-paren">(</span><em class="sig-param">data</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.write" title="永久链接至目标"></a></dt>
<dd><p>将一些 <em>data</em> 字节串写入传输。</p>
<p>此方法不会阻塞;它会缓冲数据并安排其被异步地发出。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.WriteTransport.writelines">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">writelines</code><span class="sig-paren">(</span><em class="sig-param">list_of_data</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.writelines" title="永久链接至目标"></a></dt>
<dd><p>将数据字节串的列表(或任意可迭代对象)写入传输。 这在功能上等价于在可迭代对象产生的每个元素上调用 <a class="reference internal" href="#asyncio.WriteTransport.write" title="asyncio.WriteTransport.write"><code class="xref py py-meth docutils literal notranslate"><span class="pre">write()</span></code></a>,但其实现可能更为高效。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.WriteTransport.write_eof">
<code class="sig-prename descclassname">WriteTransport.</code><code class="sig-name descname">write_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.WriteTransport.write_eof" title="永久链接至目标"></a></dt>
<dd><p>在刷新所有已缓冲数据之后关闭传输的写入端。 数据仍可以被接收。</p>
<p>如果传输(例如 SSL不支持半关闭的连接此方法会引发 <a class="reference internal" href="exceptions.html#NotImplementedError" title="NotImplementedError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NotImplementedError</span></code></a></p>
</dd></dl>
</section>
<section id="datagram-transports">
<h3>数据报传输<a class="headerlink" href="#datagram-transports" title="永久链接至标题"></a></h3>
<dl class="method">
<dt id="asyncio.DatagramTransport.sendto">
<code class="sig-prename descclassname">DatagramTransport.</code><code class="sig-name descname">sendto</code><span class="sig-paren">(</span><em class="sig-param">data</em>, <em class="sig-param">addr=None</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramTransport.sendto" title="永久链接至目标"></a></dt>
<dd><p><em>data</em> 字节串发送到 <em>addr</em> (基于传输的目标地址) 所给定的远端对等方。 如果 <em>addr</em><a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>,则将数据发送到传输创建时给定的目标地址。</p>
<p>此方法不会阻塞;它会缓冲数据并安排其被异步地发出。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.DatagramTransport.abort">
<code class="sig-prename descclassname">DatagramTransport.</code><code class="sig-name descname">abort</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramTransport.abort" title="永久链接至目标"></a></dt>
<dd><p>立即关闭传输,不会等待已提交的操作执行完毕。 已缓存的数据将会丢失。 不会接收更多的数据。 协议的 <a class="reference internal" href="#asyncio.BaseProtocol.connection_lost" title="asyncio.BaseProtocol.connection_lost"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.connection_lost()</span></code></a> 方法最终将附带 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 作为参数被调用。</p>
</dd></dl>
</section>
<section id="subprocess-transports">
<span id="asyncio-subprocess-transports"></span><h3>子进程传输<a class="headerlink" href="#subprocess-transports" title="永久链接至标题"></a></h3>
<dl class="method">
<dt id="asyncio.SubprocessTransport.get_pid">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">get_pid</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.get_pid" title="永久链接至目标"></a></dt>
<dd><p>将子进程的进程 ID 以整数形式返回。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.SubprocessTransport.get_pipe_transport">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">get_pipe_transport</code><span class="sig-paren">(</span><em class="sig-param">fd</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.get_pipe_transport" title="永久链接至目标"></a></dt>
<dd><p>返回对应于整数文件描述符 <em>fd</em> 的通信管道的传输:</p>
<ul class="simple">
<li><p><code class="docutils literal notranslate"><span class="pre">0</span></code>: 标准输入 (<em>stdin</em>) 的可读流式传输,如果子进程创建时未设置 <code class="docutils literal notranslate"><span class="pre">stdin=PIPE</span></code> 则为 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">1</span></code>: 标准输出writable streaming transport of the standard output (<em>stdout</em>) 的可写流式传输,如果子进程创建时未设置 <code class="docutils literal notranslate"><span class="pre">stdout=PIPE</span></code> 则为 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a></p></li>
<li><p><code class="docutils literal notranslate"><span class="pre">2</span></code>: 标准错误 (<em>stderr</em>) 的可写流式传输,如果子进程创建时未设置 <code class="docutils literal notranslate"><span class="pre">stderr=PIPE</span></code> 则为 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a></p></li>
<li><p>其他 <em>fd</em>: <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a></p></li>
</ul>
</dd></dl>
<dl class="method">
<dt id="asyncio.SubprocessTransport.get_returncode">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">get_returncode</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.get_returncode" title="永久链接至目标"></a></dt>
<dd><p>返回整数形式的进程返回码,或者如果还未返回则为 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>,这类似于 <a class="reference internal" href="subprocess.html#subprocess.Popen.returncode" title="subprocess.Popen.returncode"><code class="xref py py-attr docutils literal notranslate"><span class="pre">subprocess.Popen.returncode</span></code></a> 属性。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.SubprocessTransport.kill">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">kill</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.kill" title="永久链接至目标"></a></dt>
<dd><p>杀死子进程。</p>
<p>在 POSIX 系统中,函数会发送 SIGKILL 到子进程。 在 Windows 中,此方法是 <a class="reference internal" href="#asyncio.SubprocessTransport.terminate" title="asyncio.SubprocessTransport.terminate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">terminate()</span></code></a> 的别名。</p>
<p>另请参见 <a class="reference internal" href="subprocess.html#subprocess.Popen.kill" title="subprocess.Popen.kill"><code class="xref py py-meth docutils literal notranslate"><span class="pre">subprocess.Popen.kill()</span></code></a></p>
</dd></dl>
<dl class="method">
<dt id="asyncio.SubprocessTransport.send_signal">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">send_signal</code><span class="sig-paren">(</span><em class="sig-param">signal</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.send_signal" title="永久链接至目标"></a></dt>
<dd><p>发送 <em>signal</em> 编号到子进程,与 <a class="reference internal" href="subprocess.html#subprocess.Popen.send_signal" title="subprocess.Popen.send_signal"><code class="xref py py-meth docutils literal notranslate"><span class="pre">subprocess.Popen.send_signal()</span></code></a> 一样。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.SubprocessTransport.terminate">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">terminate</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.terminate" title="永久链接至目标"></a></dt>
<dd><p>停止子进程。</p>
<p>在 POSIX 系统中,此方法会发送 SIGTERM 到子进程。 在 Windows 中,则会调用 Windows API 函数 TerminateProcess() 来停止子进程。</p>
<p>另请参见 <a class="reference internal" href="subprocess.html#subprocess.Popen.terminate" title="subprocess.Popen.terminate"><code class="xref py py-meth docutils literal notranslate"><span class="pre">subprocess.Popen.terminate()</span></code></a></p>
</dd></dl>
<dl class="method">
<dt id="asyncio.SubprocessTransport.close">
<code class="sig-prename descclassname">SubprocessTransport.</code><code class="sig-name descname">close</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessTransport.close" title="永久链接至目标"></a></dt>
<dd><p>通过调用 <a class="reference internal" href="#asyncio.SubprocessTransport.kill" title="asyncio.SubprocessTransport.kill"><code class="xref py py-meth docutils literal notranslate"><span class="pre">kill()</span></code></a> 方法来杀死子进程。</p>
<p>如果子进程尚未返回,并关闭 <em>stdin</em>, <em>stdout</em><em>stderr</em> 管道的传输。</p>
</dd></dl>
</section>
</section>
<section id="protocols">
<span id="asyncio-protocol"></span><h2>协议<a class="headerlink" href="#protocols" title="永久链接至标题"></a></h2>
<p><strong>源码:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.8/Lib/asyncio/protocols.py">Lib/asyncio/protocols.py</a></p>
<hr class="docutils" />
<p>asyncio 提供了一组抽象基类,它们应当被用于实现网络协议。 这些类被设计为与 <a class="reference internal" href="#asyncio-transport"><span class="std std-ref">传输</span></a> 配合使用。</p>
<p>抽象基础协议类的子类可以实现其中的部分或全部方法。 所有这些方法都是回调:它们由传输或特定事件调用,例如当数据被接收的时候。 基础协议方法应当由相应的传输来调用。</p>
<section id="base-protocols">
<h3>基础协议<a class="headerlink" href="#base-protocols" title="永久链接至标题"></a></h3>
<dl class="class">
<dt id="asyncio.BaseProtocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">BaseProtocol</code><a class="headerlink" href="#asyncio.BaseProtocol" title="永久链接至目标"></a></dt>
<dd><p>带有所有协议的共享方法的基础协议。</p>
</dd></dl>
<dl class="class">
<dt id="asyncio.Protocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">Protocol</code><span class="sig-paren">(</span><em class="sig-param">BaseProtocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Protocol" title="永久链接至目标"></a></dt>
<dd><p>用于实现流式协议TCP, Unix 套接字等等)的基类。</p>
</dd></dl>
<dl class="class">
<dt id="asyncio.BufferedProtocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">BufferedProtocol</code><span class="sig-paren">(</span><em class="sig-param">BaseProtocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BufferedProtocol" title="永久链接至目标"></a></dt>
<dd><p>用于实现可对接收缓冲区进行手动控制的流式协议的基类。</p>
</dd></dl>
<dl class="class">
<dt id="asyncio.DatagramProtocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">DatagramProtocol</code><span class="sig-paren">(</span><em class="sig-param">BaseProtocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramProtocol" title="永久链接至目标"></a></dt>
<dd><p>用于实现数据报UDP协议的基类。</p>
</dd></dl>
<dl class="class">
<dt id="asyncio.SubprocessProtocol">
<em class="property">class </em><code class="sig-prename descclassname">asyncio.</code><code class="sig-name descname">SubprocessProtocol</code><span class="sig-paren">(</span><em class="sig-param">BaseProtocol</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessProtocol" title="永久链接至目标"></a></dt>
<dd><p>用于实现与子进程通信(单向管道)的协议的基类。</p>
</dd></dl>
</section>
<section id="base-protocol">
<h3>基础协议<a class="headerlink" href="#base-protocol" title="永久链接至标题"></a></h3>
<p>所有 asyncio 协议均可实现基础协议回调。</p>
<p class="rubric">链接回调函数</p>
<p>连接回调会在所有协议上被调用,每个成功的连接将恰好调用一次。 所有其他协议回调只能在以下两个方法之间被调用。</p>
<dl class="method">
<dt id="asyncio.BaseProtocol.connection_made">
<code class="sig-prename descclassname">BaseProtocol.</code><code class="sig-name descname">connection_made</code><span class="sig-paren">(</span><em class="sig-param">transport</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseProtocol.connection_made" title="永久链接至目标"></a></dt>
<dd><p>链接建立时被调用。</p>
<p><em>transport</em> 参数是代表连接的传输。 此协议负责将引用保存至对应的传输。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.BaseProtocol.connection_lost">
<code class="sig-prename descclassname">BaseProtocol.</code><code class="sig-name descname">connection_lost</code><span class="sig-paren">(</span><em class="sig-param">exc</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseProtocol.connection_lost" title="永久链接至目标"></a></dt>
<dd><p>链接丢失或关闭时被调用。</p>
<p>方法的参数是一个异常对象或为 <a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a>。 后者意味着收到了常规的 EOF或者连接被连接的一端取消或关闭。</p>
</dd></dl>
<p class="rubric">流控制回调函数</p>
<p>流程控制回调可由传输来调用以暂停或恢复协议所执行的写入操作。</p>
<p>请查看 <a class="reference internal" href="#asyncio.WriteTransport.set_write_buffer_limits" title="asyncio.WriteTransport.set_write_buffer_limits"><code class="xref py py-meth docutils literal notranslate"><span class="pre">set_write_buffer_limits()</span></code></a> 方法的文档了解详情。</p>
<dl class="method">
<dt id="asyncio.BaseProtocol.pause_writing">
<code class="sig-prename descclassname">BaseProtocol.</code><code class="sig-name descname">pause_writing</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseProtocol.pause_writing" title="永久链接至目标"></a></dt>
<dd><p>当传输的缓冲区超出高水位时将被调用。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.BaseProtocol.resume_writing">
<code class="sig-prename descclassname">BaseProtocol.</code><code class="sig-name descname">resume_writing</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BaseProtocol.resume_writing" title="永久链接至目标"></a></dt>
<dd><p>当传输的缓冲区降到低水位以下时将被调用。</p>
</dd></dl>
<p>如果缓冲区大小等于高水位值,则 <a class="reference internal" href="#asyncio.BaseProtocol.pause_writing" title="asyncio.BaseProtocol.pause_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">pause_writing()</span></code></a> 不会被调用:缓冲区大小必须要高于该值。</p>
<p>相反地,<a class="reference internal" href="#asyncio.BaseProtocol.resume_writing" title="asyncio.BaseProtocol.resume_writing"><code class="xref py py-meth docutils literal notranslate"><span class="pre">resume_writing()</span></code></a> 会在缓冲区大小等于或小于低水位值时被调用。 这些结束条件对于当两个水位取零值时也能确保符合预期的行为是很重要的。</p>
</section>
<section id="streaming-protocols">
<h3>流协议<a class="headerlink" href="#streaming-protocols" title="永久链接至标题"></a></h3>
<p>事件方法,例如 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_server" title="asyncio.loop.create_server"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_server()</span></code></a>, <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_unix_server" title="asyncio.loop.create_unix_server"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_unix_server()</span></code></a>, <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a>, <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_unix_connection" title="asyncio.loop.create_unix_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_unix_connection()</span></code></a>, <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_accepted_socket" title="asyncio.loop.connect_accepted_socket"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_accepted_socket()</span></code></a>, <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_read_pipe" title="asyncio.loop.connect_read_pipe"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_read_pipe()</span></code></a><a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.connect_write_pipe" title="asyncio.loop.connect_write_pipe"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.connect_write_pipe()</span></code></a> 都接受返回流式协议的工厂。</p>
<dl class="method">
<dt id="asyncio.Protocol.data_received">
<code class="sig-prename descclassname">Protocol.</code><code class="sig-name descname">data_received</code><span class="sig-paren">(</span><em class="sig-param">data</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Protocol.data_received" title="永久链接至目标"></a></dt>
<dd><p>当收到数据时被调用。 <em>data</em> 为包含入站数据的非空字节串对象。</p>
<p>数据是否会被缓冲、分块或重组取决于具体传输。 通常,你不应依赖于特定的语义而应使你的解析具有通用性和灵活性。 但是,数据总是要以正确的顺序被接收。</p>
<p>此方法在连接打开期间可以被调用任意次数。</p>
<p>但是,<a class="reference internal" href="#asyncio.Protocol.eof_received" title="asyncio.Protocol.eof_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.eof_received()</span></code></a> 最多只会被调用一次。 一旦 <cite>eof_received()</cite> 被调用,<code class="docutils literal notranslate"><span class="pre">data_received()</span></code> 就不会再被调用。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.Protocol.eof_received">
<code class="sig-prename descclassname">Protocol.</code><code class="sig-name descname">eof_received</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.Protocol.eof_received" title="永久链接至目标"></a></dt>
<dd><p>当发出信号的另一端不再继续发送数据时(例如通过调用 <a class="reference internal" href="#asyncio.WriteTransport.write_eof" title="asyncio.WriteTransport.write_eof"><code class="xref py py-meth docutils literal notranslate"><span class="pre">transport.write_eof()</span></code></a>,如果另一端也使用 asyncio 的话)被调用。</p>
<p>此方法可能返回假值 (包括 <code class="docutils literal notranslate"><span class="pre">None</span></code>),在此情况下传输将会自行关闭。 相反地,如果此方法返回真值,将以所用的协议来确定是否要关闭传输。 由于默认实现是返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>,因此它会隐式地关闭连接。</p>
<p>某些传输,包括 SSL 在内,并不支持半关闭的连接,在此情况下从该方法返回真值将导致连接被关闭。</p>
</dd></dl>
<p>状态机:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>start -&gt; connection_made
[-&gt; data_received]*
[-&gt; eof_received]?
-&gt; connection_lost -&gt; end
</pre></div>
</div>
</section>
<section id="buffered-streaming-protocols">
<h3>缓冲流协议<a class="headerlink" href="#buffered-streaming-protocols" title="永久链接至标题"></a></h3>
<div class="versionadded">
<p><span class="versionmodified added">3.7 新版功能: </span><strong>Important:</strong> this has been added to asyncio in Python 3.7
<em>on a provisional basis</em>! This is as an experimental API that
might be changed or removed completely in Python 3.8.</p>
</div>
<p>带缓冲的协议可与任何支持 <a class="reference internal" href="#streaming-protocols">流式协议</a> 的事件循环方法配合使用。</p>
<p><code class="docutils literal notranslate"><span class="pre">BufferedProtocol</span></code> 实现允许显式手动分配和控制接收缓冲区。 随后事件循环可以使用协议提供的缓冲区来避免不必要的数据复制。 这对于接收大量数据的协议来说会有明显的性能提升。 复杂的协议实现能显著地减少缓冲区分配的数量。</p>
<p>以下回调是在 <a class="reference internal" href="#asyncio.BufferedProtocol" title="asyncio.BufferedProtocol"><code class="xref py py-class docutils literal notranslate"><span class="pre">BufferedProtocol</span></code></a> 实例上被调用的:</p>
<dl class="method">
<dt id="asyncio.BufferedProtocol.get_buffer">
<code class="sig-prename descclassname">BufferedProtocol.</code><code class="sig-name descname">get_buffer</code><span class="sig-paren">(</span><em class="sig-param">sizehint</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BufferedProtocol.get_buffer" title="永久链接至目标"></a></dt>
<dd><p>调用后会分配新的接收缓冲区。</p>
<p><em>sizehint</em> 是推荐的返回缓冲区最小尺寸。 返回小于或大于 <em>sizehint</em> 推荐尺寸的缓冲区也是可接受的。 当设为 -1 时,缓冲区尺寸可以是任意的。 返回尺寸为零的缓冲区则是错误的。</p>
<p><code class="docutils literal notranslate"><span class="pre">get_buffer()</span></code> 必须返回一个实现了 <a class="reference internal" href="../c-api/buffer.html#bufferobjects"><span class="std std-ref">缓冲区协议</span></a> 的对象。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.BufferedProtocol.buffer_updated">
<code class="sig-prename descclassname">BufferedProtocol.</code><code class="sig-name descname">buffer_updated</code><span class="sig-paren">(</span><em class="sig-param">nbytes</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BufferedProtocol.buffer_updated" title="永久链接至目标"></a></dt>
<dd><p>用接收的数据更新缓冲区时被调用。</p>
<p><em>nbytes</em> 是被写入到缓冲区的字节总数。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.BufferedProtocol.eof_received">
<code class="sig-prename descclassname">BufferedProtocol.</code><code class="sig-name descname">eof_received</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.BufferedProtocol.eof_received" title="永久链接至目标"></a></dt>
<dd><p>请查看 <a class="reference internal" href="#asyncio.Protocol.eof_received" title="asyncio.Protocol.eof_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.eof_received()</span></code></a> 方法的文档。</p>
</dd></dl>
<p>在连接期间 <a class="reference internal" href="#asyncio.BufferedProtocol.get_buffer" title="asyncio.BufferedProtocol.get_buffer"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_buffer()</span></code></a> 可以被调用任意次数。 但是,<a class="reference internal" href="#asyncio.Protocol.eof_received" title="asyncio.Protocol.eof_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">protocol.eof_received()</span></code></a> 最多只能被调用一次,如果被调用,则在此之后 <a class="reference internal" href="#asyncio.BufferedProtocol.get_buffer" title="asyncio.BufferedProtocol.get_buffer"><code class="xref py py-meth docutils literal notranslate"><span class="pre">get_buffer()</span></code></a><a class="reference internal" href="#asyncio.BufferedProtocol.buffer_updated" title="asyncio.BufferedProtocol.buffer_updated"><code class="xref py py-meth docutils literal notranslate"><span class="pre">buffer_updated()</span></code></a> 不能再被调用。</p>
<p>状态机:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>start -&gt; connection_made
[-&gt; get_buffer
[-&gt; buffer_updated]?
]*
[-&gt; eof_received]?
-&gt; connection_lost -&gt; end
</pre></div>
</div>
</section>
<section id="datagram-protocols">
<h3>数据报协议<a class="headerlink" href="#datagram-protocols" title="永久链接至标题"></a></h3>
<p>数据报协议实例应当由传递给 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_datagram_endpoint" title="asyncio.loop.create_datagram_endpoint"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_datagram_endpoint()</span></code></a> 方法的协议工厂来构造。</p>
<dl class="method">
<dt id="asyncio.DatagramProtocol.datagram_received">
<code class="sig-prename descclassname">DatagramProtocol.</code><code class="sig-name descname">datagram_received</code><span class="sig-paren">(</span><em class="sig-param">data</em>, <em class="sig-param">addr</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramProtocol.datagram_received" title="永久链接至目标"></a></dt>
<dd><p>当接收到数据报时被调用。 <em>data</em> 是包含传入数据的字节串对象。 <em>addr</em> 是发送数据的对等端地址;实际的格式取决于具体传输。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.DatagramProtocol.error_received">
<code class="sig-prename descclassname">DatagramProtocol.</code><code class="sig-name descname">error_received</code><span class="sig-paren">(</span><em class="sig-param">exc</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.DatagramProtocol.error_received" title="永久链接至目标"></a></dt>
<dd><p>当前一个发送或接收操作引发 <a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-class docutils literal notranslate"><span class="pre">OSError</span></code></a> 时被调用。 <em>exc</em><a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-class docutils literal notranslate"><span class="pre">OSError</span></code></a> 的实例。</p>
<p>此方法会在当传输例如UDP检测到无法将数据报传给接收方等极少数情况下被调用。 而在大多数情况下,无法送达的数据报将被静默地丢弃。</p>
</dd></dl>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>在 BSD 系统macOS, FreeBSD 等等)上,数据报协议不支持流控制,因为没有可靠的方式来检测因写入多过包所导致的发送失败。</p>
<p>套接字总是显示为 'ready' 且多余的包会被丢弃。 有一定的可能性会引发 <a class="reference internal" href="exceptions.html#OSError" title="OSError"><code class="xref py py-class docutils literal notranslate"><span class="pre">OSError</span></code></a> 并设置 <code class="docutils literal notranslate"><span class="pre">errno</span></code><a class="reference internal" href="errno.html#errno.ENOBUFS" title="errno.ENOBUFS"><code class="xref py py-const docutils literal notranslate"><span class="pre">errno.ENOBUFS</span></code></a>;如果此异常被引发,它将被报告给 <a class="reference internal" href="#asyncio.DatagramProtocol.error_received" title="asyncio.DatagramProtocol.error_received"><code class="xref py py-meth docutils literal notranslate"><span class="pre">DatagramProtocol.error_received()</span></code></a>,在其他情况下则会被忽略。</p>
</div>
</section>
<section id="subprocess-protocols">
<span id="asyncio-subprocess-protocols"></span><h3>子进程协议<a class="headerlink" href="#subprocess-protocols" title="永久链接至标题"></a></h3>
<p>数据报协议实例应当由传递给 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a><a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_shell" title="asyncio.loop.subprocess_shell"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_shell()</span></code></a> 方法的协议工厂来构造。</p>
<dl class="method">
<dt id="asyncio.SubprocessProtocol.pipe_data_received">
<code class="sig-prename descclassname">SubprocessProtocol.</code><code class="sig-name descname">pipe_data_received</code><span class="sig-paren">(</span><em class="sig-param">fd</em>, <em class="sig-param">data</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessProtocol.pipe_data_received" title="永久链接至目标"></a></dt>
<dd><p>当子进程向其 stdout 或 stderr 管道写入数据时被调用。</p>
<p><em>fd</em> 是以整数表示的管道文件描述符。</p>
<p><em>data</em> 是包含已接收数据的非空字节串对象。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.SubprocessProtocol.pipe_connection_lost">
<code class="sig-prename descclassname">SubprocessProtocol.</code><code class="sig-name descname">pipe_connection_lost</code><span class="sig-paren">(</span><em class="sig-param">fd</em>, <em class="sig-param">exc</em><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessProtocol.pipe_connection_lost" title="永久链接至目标"></a></dt>
<dd><p>与子进程通信的其中一个管道关闭时被调用。</p>
<p><em>fd</em> 以整数表示的已关闭文件描述符。</p>
</dd></dl>
<dl class="method">
<dt id="asyncio.SubprocessProtocol.process_exited">
<code class="sig-prename descclassname">SubprocessProtocol.</code><code class="sig-name descname">process_exited</code><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#asyncio.SubprocessProtocol.process_exited" title="永久链接至目标"></a></dt>
<dd><p>子进程退出时被调用。</p>
</dd></dl>
</section>
</section>
<section id="examples">
<h2>例子<a class="headerlink" href="#examples" title="永久链接至标题"></a></h2>
<section id="tcp-echo-server">
<span id="asyncio-example-tcp-echo-server-protocol"></span><h3>TCP回应服务器<a class="headerlink" href="#tcp-echo-server" title="永久链接至标题"></a></h3>
<p>使用 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_server" title="asyncio.loop.create_server"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_server()</span></code></a> 方法创建 TCP 回显服务器,发回已接收的数据,并关闭连接:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="k">class</span> <span class="nc">EchoServerProtocol</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">Protocol</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
<span class="n">peername</span> <span class="o">=</span> <span class="n">transport</span><span class="o">.</span><span class="n">get_extra_info</span><span class="p">(</span><span class="s1">&#39;peername&#39;</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Connection from </span><span class="si">{}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">peername</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">transport</span>
<span class="k">def</span> <span class="nf">data_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Data received: </span><span class="si">{!r}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">message</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Send: </span><span class="si">{!r}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">message</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Close the client socket&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="c1"># Get a reference to the event loop as we plan to use</span>
<span class="c1"># low-level APIs.</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>
<span class="n">server</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_server</span><span class="p">(</span>
<span class="k">lambda</span><span class="p">:</span> <span class="n">EchoServerProtocol</span><span class="p">(),</span>
<span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">8888</span><span class="p">)</span>
<span class="k">async</span> <span class="k">with</span> <span class="n">server</span><span class="p">:</span>
<span class="k">await</span> <span class="n">server</span><span class="o">.</span><span class="n">serve_forever</span><span class="p">()</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<p><a class="reference internal" href="asyncio-stream.html#asyncio-tcp-echo-server-streams"><span class="std std-ref">使用流的 TCP 回显服务器</span></a> 示例,使用了高层级的 <a class="reference internal" href="asyncio-stream.html#asyncio.start_server" title="asyncio.start_server"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.start_server()</span></code></a> 函数。</p>
</div>
</section>
<section id="tcp-echo-client">
<span id="asyncio-example-tcp-echo-client-protocol"></span><h3>TCP回应客户端<a class="headerlink" href="#tcp-echo-client" title="永久链接至标题"></a></h3>
<p>使用 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a> 方法的 TCP 回显客户端,发送数据并等待,直到连接被关闭:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="k">class</span> <span class="nc">EchoClientProtocol</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">Protocol</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
<span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">on_con_lost</span>
<span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
<span class="n">transport</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Data sent: </span><span class="si">{!r}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">data_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Data received: </span><span class="si">{!r}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">()))</span>
<span class="k">def</span> <span class="nf">connection_lost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;The server closed the connection&#39;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="c1"># Get a reference to the event loop as we plan to use</span>
<span class="c1"># low-level APIs.</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>
<span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_future</span><span class="p">()</span>
<span class="n">message</span> <span class="o">=</span> <span class="s1">&#39;Hello World!&#39;</span>
<span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_connection</span><span class="p">(</span>
<span class="k">lambda</span><span class="p">:</span> <span class="n">EchoClientProtocol</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">),</span>
<span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">8888</span><span class="p">)</span>
<span class="c1"># Wait until the protocol signals that the connection</span>
<span class="c1"># is lost and close the transport.</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">await</span> <span class="n">on_con_lost</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<p><a class="reference internal" href="asyncio-stream.html#asyncio-tcp-echo-client-streams"><span class="std std-ref">使用流的 TCP 回显客户端</span></a> 示例,使用了高层级的 <a class="reference internal" href="asyncio-stream.html#asyncio.open_connection" title="asyncio.open_connection"><code class="xref py py-func docutils literal notranslate"><span class="pre">asyncio.open_connection()</span></code></a> 函数。</p>
</div>
</section>
<section id="udp-echo-server">
<span id="asyncio-udp-echo-server-protocol"></span><h3>UDP回应服务器<a class="headerlink" href="#udp-echo-server" title="永久链接至标题"></a></h3>
<p>使用 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_datagram_endpoint" title="asyncio.loop.create_datagram_endpoint"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_datagram_endpoint()</span></code></a> 方法的 UDP 回显服务器,发回已接收的数据:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="k">class</span> <span class="nc">EchoServerProtocol</span><span class="p">:</span>
<span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">transport</span>
<span class="k">def</span> <span class="nf">datagram_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
<span class="n">message</span> <span class="o">=</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Received </span><span class="si">%r</span><span class="s1"> from </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">addr</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Send </span><span class="si">%r</span><span class="s1"> to </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">addr</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">sendto</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">addr</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Starting UDP server&quot;</span><span class="p">)</span>
<span class="c1"># Get a reference to the event loop as we plan to use</span>
<span class="c1"># low-level APIs.</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>
<span class="c1"># One protocol instance will be created to serve all</span>
<span class="c1"># client requests.</span>
<span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_datagram_endpoint</span><span class="p">(</span>
<span class="k">lambda</span><span class="p">:</span> <span class="n">EchoServerProtocol</span><span class="p">(),</span>
<span class="n">local_addr</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">9999</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3600</span><span class="p">)</span> <span class="c1"># Serve for 1 hour.</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
</section>
<section id="udp-echo-client">
<span id="asyncio-udp-echo-client-protocol"></span><h3>UDP回应客户端<a class="headerlink" href="#udp-echo-client" title="永久链接至标题"></a></h3>
<p>使用 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_datagram_endpoint" title="asyncio.loop.create_datagram_endpoint"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_datagram_endpoint()</span></code></a> 方法的 UDP 回显客户端,发送数据并在收到回应时关闭传输:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="k">class</span> <span class="nc">EchoClientProtocol</span><span class="p">:</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="n">message</span>
<span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">on_con_lost</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">transport</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Send:&#39;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">sendto</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="k">def</span> <span class="nf">datagram_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">addr</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Received:&quot;</span><span class="p">,</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Close the socket&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">error_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">&#39;Error received:&#39;</span><span class="p">,</span> <span class="n">exc</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">connection_lost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Connection closed&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="c1"># Get a reference to the event loop as we plan to use</span>
<span class="c1"># low-level APIs.</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>
<span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_future</span><span class="p">()</span>
<span class="n">message</span> <span class="o">=</span> <span class="s2">&quot;Hello World!&quot;</span>
<span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_datagram_endpoint</span><span class="p">(</span>
<span class="k">lambda</span><span class="p">:</span> <span class="n">EchoClientProtocol</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">),</span>
<span class="n">remote_addr</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;127.0.0.1&#39;</span><span class="p">,</span> <span class="mi">9999</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">await</span> <span class="n">on_con_lost</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
</section>
<section id="connecting-existing-sockets">
<span id="asyncio-example-create-connection"></span><h3>链接已存在的套接字<a class="headerlink" href="#connecting-existing-sockets" title="永久链接至标题"></a></h3>
<p>附带一个协议使用 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.create_connection" title="asyncio.loop.create_connection"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.create_connection()</span></code></a> 方法,等待直到套接字接收数据:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="kn">import</span> <span class="nn">socket</span>
<span class="k">class</span> <span class="nc">MyProtocol</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">Protocol</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">on_con_lost</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="kc">None</span>
<span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">on_con_lost</span>
<span class="k">def</span> <span class="nf">connection_made</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">transport</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span> <span class="o">=</span> <span class="n">transport</span>
<span class="k">def</span> <span class="nf">data_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;Received:&quot;</span><span class="p">,</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">())</span>
<span class="c1"># We are done: close the transport;</span>
<span class="c1"># connection_lost() will be called automatically.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">connection_lost</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exc</span><span class="p">):</span>
<span class="c1"># The socket has been closed</span>
<span class="bp">self</span><span class="o">.</span><span class="n">on_con_lost</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
<span class="c1"># Get a reference to the event loop as we plan to use</span>
<span class="c1"># low-level APIs.</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>
<span class="n">on_con_lost</span> <span class="o">=</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_future</span><span class="p">()</span>
<span class="c1"># Create a pair of connected sockets</span>
<span class="n">rsock</span><span class="p">,</span> <span class="n">wsock</span> <span class="o">=</span> <span class="n">socket</span><span class="o">.</span><span class="n">socketpair</span><span class="p">()</span>
<span class="c1"># Register the socket to wait for data.</span>
<span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">create_connection</span><span class="p">(</span>
<span class="k">lambda</span><span class="p">:</span> <span class="n">MyProtocol</span><span class="p">(</span><span class="n">on_con_lost</span><span class="p">),</span> <span class="n">sock</span><span class="o">=</span><span class="n">rsock</span><span class="p">)</span>
<span class="c1"># Simulate the reception of data from the network.</span>
<span class="n">loop</span><span class="o">.</span><span class="n">call_soon</span><span class="p">(</span><span class="n">wsock</span><span class="o">.</span><span class="n">send</span><span class="p">,</span> <span class="s1">&#39;abc&#39;</span><span class="o">.</span><span class="n">encode</span><span class="p">())</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">await</span> <span class="n">protocol</span><span class="o">.</span><span class="n">on_con_lost</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">wsock</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<p>使用低层级的 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.add_reader" title="asyncio.loop.add_reader"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.add_reader()</span></code></a> 方法来注册一个 FD 的 <a class="reference internal" href="asyncio-eventloop.html#asyncio-example-watch-fd"><span class="std std-ref">监视文件描述符以读取事件</span></a> 示例。</p>
<p>使用在协程中通过 <a class="reference internal" href="asyncio-stream.html#asyncio.open_connection" title="asyncio.open_connection"><code class="xref py py-func docutils literal notranslate"><span class="pre">open_connection()</span></code></a> 函数创建的高层级流的 <a class="reference internal" href="asyncio-stream.html#asyncio-example-create-connection-streams"><span class="std std-ref">注册一个打开的套接字以等待使用流的数据</span></a> 示例。</p>
</div>
</section>
<section id="loop-subprocess-exec-and-subprocessprotocol">
<span id="asyncio-example-subprocess-proto"></span><h3>loop.subprocess_exec() 与 SubprocessProtocol<a class="headerlink" href="#loop-subprocess-exec-and-subprocessprotocol" title="永久链接至标题"></a></h3>
<p>一个使用子进程协议来获取子进程的输出并等待子进程退出的示例。</p>
<p>这个子进程是由 <a class="reference internal" href="asyncio-eventloop.html#asyncio.loop.subprocess_exec" title="asyncio.loop.subprocess_exec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loop.subprocess_exec()</span></code></a> 方法创建的:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">asyncio</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="k">class</span> <span class="nc">DateProtocol</span><span class="p">(</span><span class="n">asyncio</span><span class="o">.</span><span class="n">SubprocessProtocol</span><span class="p">):</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">exit_future</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">exit_future</span> <span class="o">=</span> <span class="n">exit_future</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span> <span class="o">=</span> <span class="nb">bytearray</span><span class="p">()</span>
<span class="k">def</span> <span class="nf">pipe_data_received</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fd</span><span class="p">,</span> <span class="n">data</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">process_exited</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">exit_future</span><span class="o">.</span><span class="n">set_result</span><span class="p">(</span><span class="kc">True</span><span class="p">)</span>
<span class="k">async</span> <span class="k">def</span> <span class="nf">get_date</span><span class="p">():</span>
<span class="c1"># Get a reference to the event loop as we plan to use</span>
<span class="c1"># low-level APIs.</span>
<span class="n">loop</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">get_running_loop</span><span class="p">()</span>
<span class="n">code</span> <span class="o">=</span> <span class="s1">&#39;import datetime; print(datetime.datetime.now())&#39;</span>
<span class="n">exit_future</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">Future</span><span class="p">(</span><span class="n">loop</span><span class="o">=</span><span class="n">loop</span><span class="p">)</span>
<span class="c1"># Create the subprocess controlled by DateProtocol;</span>
<span class="c1"># redirect the standard output into a pipe.</span>
<span class="n">transport</span><span class="p">,</span> <span class="n">protocol</span> <span class="o">=</span> <span class="k">await</span> <span class="n">loop</span><span class="o">.</span><span class="n">subprocess_exec</span><span class="p">(</span>
<span class="k">lambda</span><span class="p">:</span> <span class="n">DateProtocol</span><span class="p">(</span><span class="n">exit_future</span><span class="p">),</span>
<span class="n">sys</span><span class="o">.</span><span class="n">executable</span><span class="p">,</span> <span class="s1">&#39;-c&#39;</span><span class="p">,</span> <span class="n">code</span><span class="p">,</span>
<span class="n">stdin</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
<span class="c1"># Wait for the subprocess exit using the process_exited()</span>
<span class="c1"># method of the protocol.</span>
<span class="k">await</span> <span class="n">exit_future</span>
<span class="c1"># Close the stdout pipe.</span>
<span class="n">transport</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="c1"># Read the output which was collected by the</span>
<span class="c1"># pipe_data_received() method of the protocol.</span>
<span class="n">data</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">protocol</span><span class="o">.</span><span class="n">output</span><span class="p">)</span>
<span class="k">return</span> <span class="n">data</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;ascii&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">rstrip</span><span class="p">()</span>
<span class="n">date</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">get_date</span><span class="p">())</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Current date: </span><span class="si">{</span><span class="n">date</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
</pre></div>
</div>
<p>另请参阅使用高层级 API 编写的 <a class="reference internal" href="asyncio-subprocess.html#asyncio-example-create-subprocess-exec"><span class="std std-ref">相同示例</span></a></p>
</section>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">传输和协议</a><ul>
<li><a class="reference internal" href="#transports">传输</a><ul>
<li><a class="reference internal" href="#transports-hierarchy">传输层级</a></li>
<li><a class="reference internal" href="#base-transport">基础传输</a></li>
<li><a class="reference internal" href="#read-only-transports">只读传输</a></li>
<li><a class="reference internal" href="#write-only-transports">只写传输</a></li>
<li><a class="reference internal" href="#datagram-transports">数据报传输</a></li>
<li><a class="reference internal" href="#subprocess-transports">子进程传输</a></li>
</ul>
</li>
<li><a class="reference internal" href="#protocols">协议</a><ul>
<li><a class="reference internal" href="#base-protocols">基础协议</a></li>
<li><a class="reference internal" href="#base-protocol">基础协议</a></li>
<li><a class="reference internal" href="#streaming-protocols">流协议</a></li>
<li><a class="reference internal" href="#buffered-streaming-protocols">缓冲流协议</a></li>
<li><a class="reference internal" href="#datagram-protocols">数据报协议</a></li>
<li><a class="reference internal" href="#subprocess-protocols">子进程协议</a></li>
</ul>
</li>
<li><a class="reference internal" href="#examples">例子</a><ul>
<li><a class="reference internal" href="#tcp-echo-server">TCP回应服务器</a></li>
<li><a class="reference internal" href="#tcp-echo-client">TCP回应客户端</a></li>
<li><a class="reference internal" href="#udp-echo-server">UDP回应服务器</a></li>
<li><a class="reference internal" href="#udp-echo-client">UDP回应客户端</a></li>
<li><a class="reference internal" href="#connecting-existing-sockets">链接已存在的套接字</a></li>
<li><a class="reference internal" href="#loop-subprocess-exec-and-subprocessprotocol">loop.subprocess_exec() 与 SubprocessProtocol</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="asyncio-future.html"
title="上一章">Futures</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="asyncio-policy.html"
title="下一章">策略</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/library/asyncio-protocol.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="asyncio-policy.html" title="策略"
>下一页</a> |</li>
<li class="right" >
<a href="asyncio-future.html" title="Futures"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python 标准库</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="ipc.html" >网络和进程间通信</a> &#187;</li>
<li class="nav-item nav-item-3"><a href="asyncio.html" ><code class="xref py py-mod docutils literal notranslate"><span class="pre">asyncio</span></code> --- 异步 I/O</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>