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

来自菜鸟教程
Python/docs/3.9/library/asyncio-stream
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:流 — Python 文档}}
 
<div id="streams" class="section">
 
<div id="streams" class="section">
  
 
<span id="asyncio-streams"></span>
 
<span id="asyncio-streams"></span>
= Streams =
+
= =
  
'''Source code:''' [https://github.com/python/cpython/tree/3.9/Lib/asyncio/streams.py Lib/asyncio/streams.py]
+
'''源代码:''' [[#id1|<span id="id2" class="problematic">:source:`Lib/asyncio/streams.py`</span>]]
  
Streams are high-level async/await-ready primitives to work with
 
network connections. Streams allow sending and receiving data without
 
using callbacks or low-level protocols and transports.
 
  
Here is an example of a TCP echo client written using asyncio
+
-----
streams:
+
 
 +
流是用于处理网络连接的高级异步/等待就绪原语。 流允许在不使用回调或低级协议和传输的情况下发送和接收数据。
 +
 
 +
下面是一个使用 asyncio 流编写的 TCP 回显客户端的示例:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第17行: 第18行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
  
 
async def tcp_echo_client(message):
 
async def tcp_echo_client(message):
第34行: 第35行:
 
     await writer.wait_closed()
 
     await writer.wait_closed()
  
asyncio.run(tcp_echo_client('Hello World!'))</pre>
+
asyncio.run(tcp_echo_client('Hello World!'))</syntaxhighlight>
 
 
</div>
 
  
 
</div>
 
</div>
See also the [[#examples|Examples]] section below.
 
 
Stream Functions
 
 
The following top-level asyncio functions can be used to create
 
and work with streams:
 
 
<dl>
 
<dt>''coroutine'' <code>asyncio.</code><code>open_connection</code><span class="sig-paren">(</span>''host=None'', ''port=None'', ''\*'', ''loop=None'', ''limit=None'', ''ssl=None'', ''family=0'', ''proto=0'', ''flags=0'', ''sock=None'', ''local_addr=None'', ''server_hostname=None'', ''ssl_handshake_timeout=None''<span class="sig-paren">)</span></dt>
 
<dd><p>Establish a network connection and return a pair of
 
<code>(reader, writer)</code> objects.</p>
 
<p>The returned ''reader'' and ''writer'' objects are instances of
 
[[#asyncio.StreamReader|<code>StreamReader</code>]] and [[#asyncio.StreamWriter|<code>StreamWriter</code>]] classes.</p>
 
<p>The ''loop'' argument is optional and can always be determined
 
automatically when this function is awaited from a coroutine.</p>
 
<p>''limit'' determines the buffer size limit used by the
 
returned [[#asyncio.StreamReader|<code>StreamReader</code>]] instance. By default the ''limit''
 
is set to 64 KiB.</p>
 
<p>The rest of the arguments are passed directly to
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.create_connection()</code>]].</p>
 
<div class="versionadded">
 
 
<p><span class="versionmodified added">3.7 新版功能: </span>The ''ssl_handshake_timeout'' parameter.</p>
 
 
</div></dd></dl>
 
 
<dl>
 
<dt>''coroutine'' <code>asyncio.</code><code>start_server</code><span class="sig-paren">(</span>''client_connected_cb'', ''host=None'', ''port=None'', ''\*'', ''loop=None'', ''limit=None'', ''family=socket.AF_UNSPEC'', ''flags=socket.AI_PASSIVE'', ''sock=None'', ''backlog=100'', ''ssl=None'', ''reuse_address=None'', ''reuse_port=None'', ''ssl_handshake_timeout=None'', ''start_serving=True''<span class="sig-paren">)</span></dt>
 
<dd><p>Start a socket server.</p>
 
<p>The ''client_connected_cb'' callback is called whenever a new client
 
connection is established. It receives a <code>(reader, writer)</code> pair
 
as two arguments, instances of the [[#asyncio.StreamReader|<code>StreamReader</code>]] and
 
[[#asyncio.StreamWriter|<code>StreamWriter</code>]] classes.</p>
 
<p>''client_connected_cb'' can be a plain callable or a
 
[[../asyncio-task#coroutine|<span class="std std-ref">coroutine function</span>]]; if it is a coroutine function,
 
it will be automatically scheduled as a [[../asyncio-task#asyncio|<code>Task</code>]].</p>
 
<p>The ''loop'' argument is optional and can always be determined
 
automatically when this method is awaited from a coroutine.</p>
 
<p>''limit'' determines the buffer size limit used by the
 
returned [[#asyncio.StreamReader|<code>StreamReader</code>]] instance. By default the ''limit''
 
is set to 64 KiB.</p>
 
<p>The rest of the arguments are passed directly to
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.create_server()</code>]].</p>
 
<div class="versionadded">
 
 
<p><span class="versionmodified added">3.7 新版功能: </span>The ''ssl_handshake_timeout'' and ''start_serving'' parameters.</p>
 
 
</div></dd></dl>
 
 
Unix Sockets
 
 
<dl>
 
<dt>''coroutine'' <code>asyncio.</code><code>open_unix_connection</code><span class="sig-paren">(</span>''path=None'', ''\*'', ''loop=None'', ''limit=None'', ''ssl=None'', ''sock=None'', ''server_hostname=None'', ''ssl_handshake_timeout=None''<span class="sig-paren">)</span></dt>
 
<dd><p>Establish a Unix socket connection and return a pair of
 
<code>(reader, writer)</code>.</p>
 
<p>Similar to [[#asyncio.open_connection|<code>open_connection()</code>]] but operates on Unix sockets.</p>
 
<p>See also the documentation of [[../asyncio-eventloop#asyncio.loop|<code>loop.create_unix_connection()</code>]].</p>
 
<p>[[../intro#availability|<span class="std std-ref">Availability</span>]]: Unix.</p>
 
<div class="versionadded">
 
 
<p><span class="versionmodified added">3.7 新版功能: </span>The ''ssl_handshake_timeout'' parameter.</p>
 
  
 
</div>
 
</div>
<div class="versionchanged">
+
另请参阅下面的 [[#examples|示例]] 部分。
 
 
<p><span class="versionmodified changed">在 3.7 版更改: </span>The ''path'' parameter can now be a [[../../glossary#term-path-like-object|<span class="xref std std-term">path-like object</span>]]</p>
 
 
 
</div></dd></dl>
 
 
 
<dl>
 
<dt>''coroutine'' <code>asyncio.</code><code>start_unix_server</code><span class="sig-paren">(</span>''client_connected_cb'', ''path=None'', ''\*'', ''loop=None'', ''limit=None'', ''sock=None'', ''backlog=100'', ''ssl=None'', ''ssl_handshake_timeout=None'', ''start_serving=True''<span class="sig-paren">)</span></dt>
 
<dd><p>Start a Unix socket server.</p>
 
<p>Similar to [[#asyncio.start_server|<code>start_server()</code>]] but works with Unix sockets.</p>
 
<p>See also the documentation of [[../asyncio-eventloop#asyncio.loop|<code>loop.create_unix_server()</code>]].</p>
 
<p>[[../intro#availability|<span class="std std-ref">Availability</span>]]: Unix.</p>
 
<div class="versionadded">
 
 
 
<p><span class="versionmodified added">3.7 新版功能: </span>The ''ssl_handshake_timeout'' and ''start_serving'' parameters.</p>
 
  
</div>
+
流函数
<div class="versionchanged">
 
  
<p><span class="versionmodified changed">在 3.7 版更改: </span>The ''path'' parameter can now be a [[../../glossary#term-path-like-object|<span class="xref std std-term">path-like object</span>]].</p>
+
以下顶级异步函数可用于创建和处理流:
  
</div></dd></dl>
+
Unix 套接字
  
 
<div id="streamreader" class="section">
 
<div id="streamreader" class="section">
  
== StreamReader ==
+
== 流阅读器 ==
 
 
<dl>
 
<dt>''class'' <code>asyncio.</code><code>StreamReader</code></dt>
 
<dd><p>Represents a reader object that provides APIs to read data
 
from the IO stream.</p>
 
<p>It is not recommended to instantiate ''StreamReader'' objects
 
directly; use [[#asyncio.open_connection|<code>open_connection()</code>]] and [[#asyncio.start_server|<code>start_server()</code>]]
 
instead.</p>
 
<dl>
 
<dt>''coroutine'' <code>read</code><span class="sig-paren">(</span>''<span class="n">n</span><span class="o">=</span><span class="default_value">- 1</span>''<span class="sig-paren">)</span></dt>
 
<dd><p>Read up to ''n'' bytes. If ''n'' is not provided, or set to <code>-1</code>,
 
read until EOF and return all read bytes.</p>
 
<p>If EOF was received and the internal buffer is empty,
 
return an empty <code>bytes</code> object.</p></dd></dl>
 
 
 
<dl>
 
<dt>''coroutine'' <code>readline</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
 
<dd><p>Read one line, where &quot;line&quot; is a sequence of bytes
 
ending with <code>\n</code>.</p>
 
<p>If EOF is received and <code>\n</code> was not found, the method
 
returns partially read data.</p>
 
<p>If EOF is received and the internal buffer is empty,
 
return an empty <code>bytes</code> object.</p></dd></dl>
 
 
 
<dl>
 
<dt>''coroutine'' <code>readexactly</code><span class="sig-paren">(</span>''<span class="n">n</span>''<span class="sig-paren">)</span></dt>
 
<dd><p>Read exactly ''n'' bytes.</p>
 
<p>Raise an [[../asyncio-exceptions#asyncio|<code>IncompleteReadError</code>]] if EOF is reached before ''n''
 
can be read. Use the [[../asyncio-exceptions#asyncio.IncompleteReadError|<code>IncompleteReadError.partial</code>]]
 
attribute to get the partially read data.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''coroutine'' <code>readuntil</code><span class="sig-paren">(</span>''<span class="n">separator</span><span class="o">=</span><span class="default_value">b'\\n'</span>''<span class="sig-paren">)</span></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">StreamReader</span></span></dt>
<dd><p>Read data from the stream until ''separator'' is found.</p>
+
<dd><p>表示提供 API 以从 IO 流读取数据的读取器对象。</p>
<p>On success, the data and separator will be removed from the
+
<p>不建议直接实例化''StreamReader''对象; 改用 <code>open_connection()</code> <code>start_server()</code></p>
internal buffer (consumed). Returned data will include the
 
separator at the end.</p>
 
<p>If the amount of data read exceeds the configured stream limit, a
 
[[../asyncio-exceptions#asyncio|<code>LimitOverrunError</code>]] exception is raised, and the data
 
is left in the internal buffer and can be read again.</p>
 
<p>If EOF is reached before the complete separator is found,
 
an [[../asyncio-exceptions#asyncio|<code>IncompleteReadError</code>]] exception is raised, and the internal
 
buffer is reset. The [[../asyncio-exceptions#asyncio.IncompleteReadError|<code>IncompleteReadError.partial</code>]] attribute
 
may contain a portion of the separator.</p>
 
<div class="versionadded">
 
 
 
<p><span class="versionmodified added">3.5.2 新版功能.</span></p>
 
 
 
</div></dd></dl>
 
 
 
 
<dl>
 
<dl>
<dt><code>at_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">at_eof</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return <code>True</code> if the buffer is empty and <code>feed_eof()</code>
+
<dd><p>如果缓冲区为空并且 <code>feed_eof()</code> 被调用,则返回 <code>True</code></p></dd></dl>
was called.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
第188行: 第65行:
 
<div id="streamwriter" class="section">
 
<div id="streamwriter" class="section">
  
== StreamWriter ==
+
== 流写入器 ==
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncio.</code><code>StreamWriter</code></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncio.</span></span><span class="sig-name descname"><span class="pre">StreamWriter</span></span></dt>
<dd><p>Represents a writer object that provides APIs to write data
+
<dd><p>表示提供 API 以将数据写入 IO 流的编写器对象。</p>
to the IO stream.</p>
+
<p>不建议直接实例化''StreamWriter''对象; 改用 <code>open_connection()</code> <code>start_server()</code></p>
<p>It is not recommended to instantiate ''StreamWriter'' objects
 
directly; use [[#asyncio.open_connection|<code>open_connection()</code>]] and [[#asyncio.start_server|<code>start_server()</code>]]
 
instead.</p>
 
 
<dl>
 
<dl>
<dt><code>write</code><span class="sig-paren">(</span>''<span class="n">data</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">write</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">data</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>The method attempts to write the ''data'' to the underlying socket immediately.
+
<dd><p>该方法尝试立即将 ''data'' 写入底层套接字。 如果失败,数据将在内部写入缓冲区中排队,直到可以发送为止。</p>
If that fails, the data is queued in an internal write buffer until it can be
+
<p>该方法应与 <code>drain()</code> 方法一起使用:</p>
sent.</p>
 
<p>The method should be used along with the <code>drain()</code> method:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>stream.write(data)
+
<syntaxhighlight lang="python3">stream.write(data)
await stream.drain()</pre>
+
await stream.drain()</syntaxhighlight>
  
 
</div>
 
</div>
第215行: 第87行:
  
 
<dl>
 
<dl>
<dt><code>writelines</code><span class="sig-paren">(</span>''<span class="n">data</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">writelines</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">data</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>The method writes a list (or any iterable) of bytes to the underlying socket
+
<dd><p>该方法立即将字节列表(或任何可迭代的)写入底层套接字。 如果失败,数据将在内部写入缓冲区中排队,直到可以发送为止。</p>
immediately.
+
<p>该方法应与 <code>drain()</code> 方法一起使用:</p>
If that fails, the data is queued in an internal write buffer until it can be
 
sent.</p>
 
<p>The method should be used along with the <code>drain()</code> method:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>stream.writelines(lines)
+
<syntaxhighlight lang="python3">stream.writelines(lines)
await stream.drain()</pre>
+
await stream.drain()</syntaxhighlight>
  
 
</div>
 
</div>
第233行: 第102行:
  
 
<dl>
 
<dl>
<dt><code>close</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">close</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>The method closes the stream and the underlying socket.</p>
+
<dd><p>该方法关闭流和底层套接字。</p>
<p>The method should be used along with the <code>wait_closed()</code> method:</p>
+
<p>该方法应与 <code>wait_closed()</code> 方法一起使用:</p>
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>stream.close()
+
<syntaxhighlight lang="python3">stream.close()
await stream.wait_closed()</pre>
+
await stream.wait_closed()</syntaxhighlight>
  
 
</div>
 
</div>
第248行: 第117行:
  
 
<dl>
 
<dl>
<dt><code>can_write_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">can_write_eof</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Return <code>True</code> if the underlying transport supports
+
<dd><p>如果底层传输支持 [[#asyncio.StreamWriter.write_eof|write_eof()]] 方法,则返回 <code>True</code>,否则返回 <code>False</code></p></dd></dl>
the [[#asyncio.StreamWriter.write_eof|<code>write_eof()</code>]] method, <code>False</code> otherwise.</p></dd></dl>
 
 
 
<dl>
 
<dt><code>write_eof</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
 
<dd><p>Close the write end of the stream after the buffered write
 
data is flushed.</p></dd></dl>
 
 
 
<dl>
 
<dt><code>transport</code></dt>
 
<dd><p>Return the underlying asyncio transport.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>get_extra_info</code><span class="sig-paren">(</span>''<span class="n">name</span>'', ''<span class="n">default</span><span class="o">=</span><span class="default_value">None</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">write_eof</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Access optional transport information; see
+
<dd><p>缓冲的写入数据刷新后关闭流的写入端。</p></dd></dl>
[[../asyncio-protocol#asyncio.BaseTransport|<code>BaseTransport.get_extra_info()</code>]] for details.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''coroutine'' <code>drain</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">transport</span></span></dt>
<dd><p>Wait until it is appropriate to resume writing to the stream.
+
<dd><p>返回底层异步传输。</p></dd></dl>
Example:</p>
 
<div class="highlight-python3 notranslate">
 
 
 
<div class="highlight">
 
 
 
<pre>writer.write(data)
 
await writer.drain()</pre>
 
 
 
</div>
 
 
 
</div>
 
<p>This is a flow control method that interacts with the underlying
 
IO write buffer. When the size of the buffer reaches
 
the high watermark, ''drain()'' blocks until the size of the
 
buffer is drained down to the low watermark and writing can
 
be resumed. When there is nothing to wait for, the [[#asyncio.StreamWriter.drain|<code>drain()</code>]]
 
returns immediately.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>is_closing</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">get_extra_info</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">name</span></span>'', ''<span class="n"><span class="pre">default</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">None</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Return <code>True</code> if the stream is closed or in the process of
+
<dd><p>访问可选的交通信息; 有关详细信息,请参阅 [[../asyncio-protocol#asyncio.BaseTransport|BaseTransport.get_extra_info()]]。</p></dd></dl>
being closed.</p>
 
<div class="versionadded">
 
 
 
<p><span class="versionmodified added">3.7 新版功能.</span></p>
 
 
 
</div></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''coroutine'' <code>wait_closed</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">is_closing</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Wait until the stream is closed.</p>
+
<dd><p>如果流已关闭或正在关闭,则返回 <code>True</code></p>
<p>Should be called after [[#asyncio.StreamWriter.close|<code>close()</code>]] to wait until the underlying
 
connection is closed.</p>
 
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.7 新版功能.</span></p>
+
<p><span class="versionmodified added">3.7 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
第313行: 第146行:
 
<div id="examples" class="section">
 
<div id="examples" class="section">
  
== Examples ==
+
== 例子 ==
  
 
<div id="tcp-echo-client-using-streams" class="section">
 
<div id="tcp-echo-client-using-streams" class="section">
  
 
<span id="asyncio-tcp-echo-client-streams"></span>
 
<span id="asyncio-tcp-echo-client-streams"></span>
=== TCP echo client using streams ===
+
=== 使用流的 TCP 回显客户端 ===
  
TCP echo client using the [[#asyncio.open_connection|<code>asyncio.open_connection()</code>]] function:
+
使用 <code>asyncio.open_connection()</code> 函数的 TCP 回显客户端:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第326行: 第159行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
  
 
async def tcp_echo_client(message):
 
async def tcp_echo_client(message):
第341行: 第174行:
 
     writer.close()
 
     writer.close()
  
asyncio.run(tcp_echo_client('Hello World!'))</pre>
+
asyncio.run(tcp_echo_client('Hello World!'))</syntaxhighlight>
  
 
</div>
 
</div>
第348行: 第181行:
 
<div class="admonition seealso">
 
<div class="admonition seealso">
  
参见
+
也可以看看
  
The [[../asyncio-protocol#asyncio-example-tcp-echo-client-protocol|<span class="std std-ref">TCP echo client protocol</span>]]
+
[[../asyncio-protocol#asyncio-example-tcp-echo-client-protocol|TCP 回显客户端协议]] 示例使用低级 <code>loop.create_connection()</code> 方法。
example uses the low-level [[../asyncio-eventloop#asyncio.loop|<code>loop.create_connection()</code>]] method.
 
  
  
第360行: 第192行:
  
 
<span id="asyncio-tcp-echo-server-streams"></span>
 
<span id="asyncio-tcp-echo-server-streams"></span>
=== TCP echo server using streams ===
+
=== 使用流的 TCP 回显服务器 ===
  
TCP echo server using the [[#asyncio.start_server|<code>asyncio.start_server()</code>]] function:
+
使用 <code>asyncio.start_server()</code> 函数的 TCP 回显服务器:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第368行: 第200行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
  
 
async def handle_echo(reader, writer):
 
async def handle_echo(reader, writer):
第375行: 第207行:
 
     addr = writer.get_extra_info('peername')
 
     addr = writer.get_extra_info('peername')
  
     print(f&quot;Received {message!r} from {addr!r}&quot;)
+
     print(f"Received {message!r} from {addr!r}")
  
     print(f&quot;Send: {message!r}&quot;)
+
     print(f"Send: {message!r}")
 
     writer.write(data)
 
     writer.write(data)
 
     await writer.drain()
 
     await writer.drain()
  
     print(&quot;Close the connection&quot;)
+
     print("Close the connection")
 
     writer.close()
 
     writer.close()
  
第388行: 第220行:
 
         handle_echo, '127.0.0.1', 8888)
 
         handle_echo, '127.0.0.1', 8888)
  
     addr = server.sockets[0].getsockname()
+
     addrs = ', '.join(str(sock.getsockname()) for sock in server.sockets)
     print(f'Serving on {addr}')
+
     print(f'Serving on {addrs}')
  
 
     async with server:
 
     async with server:
 
         await server.serve_forever()
 
         await server.serve_forever()
  
asyncio.run(main())</pre>
+
asyncio.run(main())</syntaxhighlight>
  
 
</div>
 
</div>
第401行: 第233行:
 
<div class="admonition seealso">
 
<div class="admonition seealso">
  
参见
+
也可以看看
  
The [[../asyncio-protocol#asyncio-example-tcp-echo-server-protocol|<span class="std std-ref">TCP echo server protocol</span>]]
+
[[../asyncio-protocol#asyncio-example-tcp-echo-server-protocol|TCP 回显服务器协议]] 示例使用 <code>loop.create_server()</code> 方法。
example uses the [[../asyncio-eventloop#asyncio.loop|<code>loop.create_server()</code>]] method.
 
  
  
第412行: 第243行:
 
<div id="get-http-headers" class="section">
 
<div id="get-http-headers" class="section">
  
=== Get HTTP headers ===
+
=== 获取 HTTP 标头 ===
  
Simple example querying HTTP headers of the URL passed on the command line:
+
查询通过命令行传递的 URL 的 HTTP 标头的简单示例:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第420行: 第251行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
 
import urllib.parse
 
import urllib.parse
 
import sys
 
import sys
第434行: 第265行:
  
 
     query = (
 
     query = (
         f&quot;HEAD {url.path or '/'} HTTP/1.0\r\n&quot;
+
         f"HEAD {url.path or '/'} HTTP/1.0\r\n"
         f&quot;Host: {url.hostname}\r\n&quot;
+
         f"Host: {url.hostname}\r\n"
         f&quot;\r\n&quot;
+
         f"\r\n"
 
     )
 
     )
  
第447行: 第278行:
 
         line = line.decode('latin1').rstrip()
 
         line = line.decode('latin1').rstrip()
 
         if line:
 
         if line:
             print(f'HTTP header&gt; {line}')
+
             print(f'HTTP header> {line}')
  
 
     # Ignore the body, close the socket
 
     # Ignore the body, close the socket
第453行: 第284行:
  
 
url = sys.argv[1]
 
url = sys.argv[1]
asyncio.run(print_http_headers(url))</pre>
+
asyncio.run(print_http_headers(url))</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
Usage:
+
用法:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第464行: 第295行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>python example.py http://example.com/path/page.html</pre>
+
<syntaxhighlight lang="python3">python example.py http://example.com/path/page.html</syntaxhighlight>
  
 
</div>
 
</div>
  
 
</div>
 
</div>
or with HTTPS:
+
或使用 HTTPS:
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第475行: 第306行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>python example.py https://example.com/path/page.html</pre>
+
<syntaxhighlight lang="python3">python example.py https://example.com/path/page.html</syntaxhighlight>
  
 
</div>
 
</div>
第485行: 第316行:
  
 
<span id="asyncio-example-create-connection-streams"></span>
 
<span id="asyncio-example-create-connection-streams"></span>
=== Register an open socket to wait for data using streams ===
+
=== 注册一个打开的套接字以使用流等待数据 ===
  
Coroutine waiting until a socket receives data using the
+
协程等待套接字使用 <code>open_connection()</code> 函数接收数据:
[[#asyncio.open_connection|<code>open_connection()</code>]] function:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第494行: 第324行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncio
+
<syntaxhighlight lang="python3">import asyncio
 
import socket
 
import socket
  
第515行: 第345行:
  
 
     # Got data, we are done: close the socket
 
     # Got data, we are done: close the socket
     print(&quot;Received:&quot;, data.decode())
+
     print("Received:", data.decode())
 
     writer.close()
 
     writer.close()
  
第521行: 第351行:
 
     wsock.close()
 
     wsock.close()
  
asyncio.run(wait_for_data())</pre>
+
asyncio.run(wait_for_data())</syntaxhighlight>
  
 
</div>
 
</div>
第528行: 第358行:
 
<div class="admonition seealso">
 
<div class="admonition seealso">
  
参见
+
也可以看看
 +
 
 +
[[../asyncio-protocol#asyncio-example-create-connection|注册一个打开的套接字以使用协议等待数据]]示例使用低级协议和<code>loop.create_connection()</code>方法。
  
The [[../asyncio-protocol#asyncio-example-create-connection|<span class="std std-ref">register an open socket to wait for data using a protocol</span>]] example uses a low-level protocol and
+
[[../asyncio-eventloop#asyncio-example-watch-fd|watch a file descriptor for read events]] 示例使用低级 [[../asyncio-eventloop#asyncio.loop|loop.add_reader()]] 方法来监视文件描述符。
the [[../asyncio-eventloop#asyncio.loop|<code>loop.create_connection()</code>]] method.
 
  
The [[../asyncio-eventloop#asyncio-example-watch-fd|<span class="std std-ref">watch a file descriptor for read events</span>]] example uses the low-level
 
[[../asyncio-eventloop#asyncio.loop|<code>loop.add_reader()</code>]] method to watch a file descriptor.
 
  
 +
</div>
  
 
</div>
 
</div>
第542行: 第372行:
  
 
</div>
 
</div>
 +
<div class="clearer">
 +
 +
  
 
</div>
 
</div>
  
[[Category:Python 3.9 中文文档]]
+
[[Category:Python 3.9 文档]]

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

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



流是用于处理网络连接的高级异步/等待就绪原语。 流允许在不使用回调或低级协议和传输的情况下发送和接收数据。

下面是一个使用 asyncio 流编写的 TCP 回显客户端的示例:

import asyncio

async def tcp_echo_client(message):
    reader, writer = await asyncio.open_connection(
        '127.0.0.1', 8888)

    print(f'Send: {message!r}')
    writer.write(message.encode())
    await writer.drain()

    data = await reader.read(100)
    print(f'Received: {data.decode()!r}')

    print('Close the connection')
    writer.close()
    await writer.wait_closed()

asyncio.run(tcp_echo_client('Hello World!'))

另请参阅下面的 示例 部分。

流函数

以下顶级异步函数可用于创建和处理流:

Unix 套接字

流阅读器

class asyncio.StreamReader

表示提供 API 以从 IO 流读取数据的读取器对象。

不建议直接实例化StreamReader对象; 改用 open_connection()start_server()

at_eof()

如果缓冲区为空并且 feed_eof() 被调用,则返回 True


流写入器

class asyncio.StreamWriter

表示提供 API 以将数据写入 IO 流的编写器对象。

不建议直接实例化StreamWriter对象; 改用 open_connection()start_server()

write(data)

该方法尝试立即将 data 写入底层套接字。 如果失败,数据将在内部写入缓冲区中排队,直到可以发送为止。

该方法应与 drain() 方法一起使用:

stream.write(data)
await stream.drain()
writelines(data)

该方法立即将字节列表(或任何可迭代的)写入底层套接字。 如果失败,数据将在内部写入缓冲区中排队,直到可以发送为止。

该方法应与 drain() 方法一起使用:

stream.writelines(lines)
await stream.drain()
close()

该方法关闭流和底层套接字。

该方法应与 wait_closed() 方法一起使用:

stream.close()
await stream.wait_closed()
can_write_eof()

如果底层传输支持 write_eof() 方法,则返回 True,否则返回 False

write_eof()

缓冲的写入数据刷新后关闭流的写入端。

transport

返回底层异步传输。

get_extra_info(name, default=None)

访问可选的交通信息; 有关详细信息,请参阅 BaseTransport.get_extra_info()

is_closing()

如果流已关闭或正在关闭,则返回 True

3.7 版中的新功能。


例子

使用流的 TCP 回显客户端

使用 asyncio.open_connection() 函数的 TCP 回显客户端:

import asyncio

async def tcp_echo_client(message):
    reader, writer = await asyncio.open_connection(
        '127.0.0.1', 8888)

    print(f'Send: {message!r}')
    writer.write(message.encode())

    data = await reader.read(100)
    print(f'Received: {data.decode()!r}')

    print('Close the connection')
    writer.close()

asyncio.run(tcp_echo_client('Hello World!'))

也可以看看

TCP 回显客户端协议 示例使用低级 loop.create_connection() 方法。


使用流的 TCP 回显服务器

使用 asyncio.start_server() 函数的 TCP 回显服务器:

import asyncio

async def handle_echo(reader, writer):
    data = await reader.read(100)
    message = data.decode()
    addr = writer.get_extra_info('peername')

    print(f"Received {message!r} from {addr!r}")

    print(f"Send: {message!r}")
    writer.write(data)
    await writer.drain()

    print("Close the connection")
    writer.close()

async def main():
    server = await asyncio.start_server(
        handle_echo, '127.0.0.1', 8888)

    addrs = ', '.join(str(sock.getsockname()) for sock in server.sockets)
    print(f'Serving on {addrs}')

    async with server:
        await server.serve_forever()

asyncio.run(main())

也可以看看

TCP 回显服务器协议 示例使用 loop.create_server() 方法。


获取 HTTP 标头

查询通过命令行传递的 URL 的 HTTP 标头的简单示例:

import asyncio
import urllib.parse
import sys

async def print_http_headers(url):
    url = urllib.parse.urlsplit(url)
    if url.scheme == 'https':
        reader, writer = await asyncio.open_connection(
            url.hostname, 443, ssl=True)
    else:
        reader, writer = await asyncio.open_connection(
            url.hostname, 80)

    query = (
        f"HEAD {url.path or '/'} HTTP/1.0\r\n"
        f"Host: {url.hostname}\r\n"
        f"\r\n"
    )

    writer.write(query.encode('latin-1'))
    while True:
        line = await reader.readline()
        if not line:
            break

        line = line.decode('latin1').rstrip()
        if line:
            print(f'HTTP header> {line}')

    # Ignore the body, close the socket
    writer.close()

url = sys.argv[1]
asyncio.run(print_http_headers(url))

用法:

python example.py http://example.com/path/page.html

或使用 HTTPS:

python example.py https://example.com/path/page.html

注册一个打开的套接字以使用流等待数据

协程等待套接字使用 open_connection() 函数接收数据:

import asyncio
import socket

async def wait_for_data():
    # Get a reference to the current event loop because
    # we want to access low-level APIs.
    loop = asyncio.get_running_loop()

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

    # Register the open socket to wait for data.
    reader, writer = await asyncio.open_connection(sock=rsock)

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

    # Wait for data
    data = await reader.read(100)

    # Got data, we are done: close the socket
    print("Received:", data.decode())
    writer.close()

    # Close the second socket
    wsock.close()

asyncio.run(wait_for_data())

也可以看看

注册一个打开的套接字以使用协议等待数据示例使用低级协议和loop.create_connection()方法。

watch a file descriptor for read events 示例使用低级 loop.add_reader() 方法来监视文件描述符。