“Python/docs/3.9/library/asyncore”的版本间差异

来自菜鸟教程
Python/docs/3.9/library/asyncore
跳转至:导航、​搜索
(autoload)
 
(Page commit)
 
第1行: 第1行:
 +
{{DISPLAYTITLE:asyncore — 异步套接字处理程序 — Python 文档}}
 
<div id="module-asyncore" class="section">
 
<div id="module-asyncore" class="section">
  
 
<span id="asyncore-asynchronous-socket-handler"></span>
 
<span id="asyncore-asynchronous-socket-handler"></span>
= [[#module-asyncore|<code>asyncore</code>]] --- Asynchronous socket handler =
+
= asyncore — 异步套接字处理程序 =
  
'''Source code:''' [https://github.com/python/cpython/tree/3.9/Lib/asyncore.py Lib/asyncore.py]
+
'''源代码:''' [[#id1|<span id="id2" class="problematic">:source:`Lib/asyncore.py`</span>]]
  
 
<div class="deprecated">
 
<div class="deprecated">
  
<span class="versionmodified deprecated">3.6 版后已移除: </span>Please use [[../asyncio#module-asyncio|<code>asyncio</code>]] instead.
+
<span class="versionmodified deprecated"> 3.6 版起已弃用:</span>请改用 [[../asyncio#module-asyncio|asyncio]]
  
  
 
</div>
 
</div>
 +
 +
-----
 +
 
<div class="admonition note">
 
<div class="admonition note">
  
注解
+
笔记
  
This module exists for backwards compatibility only. For new code we
+
该模块的存在只是为了向后兼容。 对于新代码,我们建议使用 [[../asyncio#module-asyncio|asyncio]]
recommend using [[../asyncio#module-asyncio|<code>asyncio</code>]].
 
  
  
 
</div>
 
</div>
This module provides the basic infrastructure for writing asynchronous socket
+
该模块提供了用于编写异步套接字服务客户端和服务器的基本基础结构。
service clients and servers.
 
  
There are only two ways to have a program on a single processor do &quot;more than
+
只有两种方法可以让单个处理器上的程序“一次做不止一件事情”。 多线程编程是最简单和最流行的方法,但还有另一种非常不同的技术,它可以让您拥有多线程的几乎所有优点,而无需实际使用多线程。 只有当您的程序在很大程度上受 I/O 限制时,它才真正实用。 如果您的程序受处理器限制,那么抢占式调度线程可能是您真正需要的。 然而,网络服务器很少受处理器限制。
one thing at a time.&quot; Multi-threaded programming is the simplest and most
 
popular way to do it, but there is another very different technique, that lets
 
you have nearly all the advantages of multi-threading, without actually using
 
multiple threads. It's really only practical if your program is largely I/O
 
bound. If your program is processor bound, then pre-emptive scheduled threads
 
are probably what you really need. Network servers are rarely processor
 
bound, however.
 
  
If your operating system supports the <code>select()</code> system call in its I/O
+
如果您的操作系统在其 I/O 库中支持 [X38X] 系统调用(并且几乎都支持),那么您可以使用它同时处理多个通信通道; 在您的 I/O 在“后台”进行时做其他工作。 尽管这种策略看起来很奇怪和复杂,尤其是一开始,它在很多方面比多线程编程更容易理解和控制。 [[#module-asyncore|asyncore]] 模块为您解决了许多难题,使构建复杂的高性能网络服务器和客户端的任务变得轻而易举。 对于“对话”应用程序和协议,配套的 [[../asynchat#module-asynchat|asynchat]] 模块是无价的。
library (and nearly all do), then you can use it to juggle multiple
 
communication channels at once; doing other work while your I/O is taking
 
place in the &quot;background.&quot; Although this strategy can seem strange and
 
complex, especially at first, it is in many ways easier to understand and
 
control than multi-threaded programming. The [[#module-asyncore|<code>asyncore</code>]] module solves
 
many of the difficult problems for you, making the task of building
 
sophisticated high-performance network servers and clients a snap. For
 
&quot;conversational&quot; applications and protocols the companion [[../asynchat#module-asynchat|<code>asynchat</code>]]
 
module is invaluable.
 
  
The basic idea behind both modules is to create one or more network
+
这两个模块背后的基本思想是创建一个或多个网络 ''通道'' 、类 [[#asyncore.dispatcher|asyncore.dispatcher]] [[../asynchat#asynchat|asynchat.async_chat]] 的实例。 创建通道将它们添加到全局地图中,如果您没有提供自己的 ''地图'' ,则由 [[#asyncore.loop|loop()]] 函数使用。
''channels'', instances of class [[#asyncore.dispatcher|<code>asyncore.dispatcher</code>]] and
 
[[../asynchat#asynchat|<code>asynchat.async_chat</code>]]. Creating the channels adds them to a global
 
map, used by the [[#asyncore.loop|<code>loop()</code>]] function if you do not provide it with your own
 
''map''.
 
  
Once the initial channel(s) is(are) created, calling the [[#asyncore.loop|<code>loop()</code>]] function
+
一旦创建了初始通道,调用 [[#asyncore.loop|loop()]] 函数激活通道服务,该服务一直持续到最后一个通道(包括在异步服务期间添加到地图的任何通道)是关闭。
activates channel service, which continues until the last channel (including
 
any that have been added to the map during asynchronous service) is closed.
 
  
 
<dl>
 
<dl>
<dt><code>asyncore.</code><code>loop</code><span class="sig-paren">(</span><span class="optional">[</span>''timeout''<span class="optional">[</span>, ''use_poll''<span class="optional">[</span>, ''map''<span class="optional">[</span>, ''count''<span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-prename descclassname"><span class="pre">asyncore.</span></span><span class="sig-name descname"><span class="pre">loop</span></span><span class="sig-paren">(</span><span class="optional">[</span>''<span class="pre">timeout</span>''<span class="optional">[</span>, ''<span class="pre">use_poll</span>''<span class="optional">[</span>, ''<span class="pre">map</span>''<span class="optional">[</span>, ''<span class="pre">count</span>''<span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="optional">]</span><span class="sig-paren">)</span></dt>
<dd><p>Enter a polling loop that terminates after count passes or all open
+
<dd><p>进入一个轮询循环,该循环在计数通过或所有打开的通道都已关闭后终止。 所有参数都是可选的。 ''count'' 参数默认为 <code>None</code>,导致循环仅在所有通道都已关闭时终止。 ''timeout'' 参数为适当的 [[../select#select|select()]] [[../select#select|poll()]] 调用设置超时参数,以秒为单位; 默认值为 30 秒。 ''use_poll'' 参数,如果为真,则表示 [[../select#select|poll()]] 应该优先于 [[../select#select|select()]](默认为 <code>False</code>.</p>
channels have been closed. All arguments are optional. The ''count''
+
<p>''map'' 参数是一个字典,其项目是要观看的频道。 当通道关闭时,它们会从它们的地图中删除。 如果省略 ''map'',则使用全局映射。 频道([[#asyncore.dispatcher|asyncore.dispatcher]][[../asynchat#asynchat|asynchat.async_chat]] 及其子类的实例)可以在地图中自由混合。</p></dd></dl>
parameter defaults to <code>None</code>, resulting in the loop terminating only when all
 
channels have been closed. The ''timeout'' argument sets the timeout
 
parameter for the appropriate [[../select#select|<code>select()</code>]] or [[../select#select|<code>poll()</code>]]
 
call, measured in seconds; the default is 30 seconds. The ''use_poll''
 
parameter, if true, indicates that [[../select#select|<code>poll()</code>]] should be used in
 
preference to [[../select#select|<code>select()</code>]] (the default is <code>False</code>).</p>
 
<p>The ''map'' parameter is a dictionary whose items are the channels to watch.
 
As channels are closed they are deleted from their map. If ''map'' is
 
omitted, a global map is used. Channels (instances of
 
[[#asyncore.dispatcher|<code>asyncore.dispatcher</code>]], [[../asynchat#asynchat|<code>asynchat.async_chat</code>]] and subclasses
 
thereof) can freely be mixed in the map.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt>''class'' <code>asyncore.</code><code>dispatcher</code></dt>
+
<dt>''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncore.</span></span><span class="sig-name descname"><span class="pre">dispatcher</span></span></dt>
<dd><p>The [[#asyncore.dispatcher|<code>dispatcher</code>]] class is a thin wrapper around a low-level socket
+
<dd><p>[[#asyncore.dispatcher|dispatcher]] 类是一个围绕低级套接字对象的瘦包装器。 为了使它更有用,它有一些从异步循环调用的事件处理方法。 否则,它可以被视为一个普通的非阻塞套接字对象。</p>
object. To make it more useful, it has a few methods for event-handling
+
<p>在某些时间或在某些连接状态下触发低级事件告诉异步循环某些高级事件已经发生。 例如,如果我们要求一个套接字连接到另一台主机,当套接字第一次变为可写时,我们就知道已经建立了连接(此时您知道您可以期望成功写入它) )。 隐含的更高级别的事件是:</p>
which are called from the asynchronous loop. Otherwise, it can be treated
 
as a normal non-blocking socket object.</p>
 
<p>The firing of low-level events at certain times or in certain connection
 
states tells the asynchronous loop that certain higher-level events have
 
taken place. For example, if we have asked for a socket to connect to
 
another host, we know that the connection has been made when the socket
 
becomes writable for the first time (at this point you know that you may
 
write to it with the expectation of success). The implied higher-level
 
events are:</p>
 
 
{|
 
{|
!width="35%"| <p>Event</p>
+
!width="35%"| <p>事件</p>
!width="65%"| <p>Description</p>
+
!width="65%"| <p>说明</p>
 
|-
 
|-
 
| <p><code>handle_connect()</code></p>
 
| <p><code>handle_connect()</code></p>
| <p>Implied by the first read or write
+
| <p>由第一个读或写事件暗示</p>
event</p>
 
 
|-
 
|-
 
| <p><code>handle_close()</code></p>
 
| <p><code>handle_close()</code></p>
| <p>Implied by a read event with no data
+
| <p>由没有可用数据的读取事件暗示</p>
available</p>
 
 
|-
 
|-
 
| <p><code>handle_accepted()</code></p>
 
| <p><code>handle_accepted()</code></p>
| <p>Implied by a read event on a listening
+
| <p>由侦听套接字上的读取事件暗示</p>
socket</p>
 
 
|}
 
|}
  
<p>During asynchronous processing, each mapped channel's [[#asyncore.dispatcher.readable|<code>readable()</code>]] and
+
<p>在异步处理过程中,每个映射通道的 [[#asyncore.dispatcher.readable|readable()]] [[#asyncore.dispatcher.writable|writable()]] 方法用于确定该通道的套接字是否应添加到通道列表 <code>select()</code>ed或 <code>poll()</code>ed 用于读取和写入事件。</p>
[[#asyncore.dispatcher.writable|<code>writable()</code>]] methods are used to determine whether the channel's socket
+
<p>因此,通道事件集大于基本套接字事件。 可以在您的子类中覆盖的全套方法如下:</p>
should be added to the list of channels <code>select()</code>ed or
 
<code>poll()</code>ed for read and write events.</p>
 
<p>Thus, the set of channel events is larger than the basic socket events. The
 
full set of methods that can be overridden in your subclass follows:</p>
 
 
<dl>
 
<dl>
<dt><code>handle_read</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">handle_read</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called when the asynchronous loop detects that a <code>read()</code> call on the
+
<dd><p>当异步循环检测到通道套接字上的 <code>read()</code> 调用将成功时调用。</p></dd></dl>
channel's socket will succeed.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>handle_write</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">handle_write</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called when the asynchronous loop detects that a writable socket can be
+
<dd><p>当异步循环检测到可以写入可写套接字时调用。 通常,此方法将实现必要的性能缓冲。 例如:</p>
written. Often this method will implement the necessary buffering for
 
performance. For example:</p>
 
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
  
 
<div class="highlight">
 
<div class="highlight">
  
<pre>def handle_write(self):
+
<syntaxhighlight lang="python3">def handle_write(self):
 
     sent = self.send(self.buffer)
 
     sent = self.send(self.buffer)
     self.buffer = self.buffer[sent:]</pre>
+
     self.buffer = self.buffer[sent:]</syntaxhighlight>
  
 
</div>
 
</div>
第129行: 第79行:
  
 
<dl>
 
<dl>
<dt><code>handle_expt</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">handle_expt</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called when there is out of band (OOB) data for a socket connection. This
+
<dd><p>当套接字连接有带外 (OOB) 数据时调用。 这几乎永远不会发生,因为 OOB 很少被支持并且很少使用。</p></dd></dl>
will almost never happen, as OOB is tenuously supported and rarely used.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>handle_connect</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">handle_connect</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called when the active opener's socket actually makes a connection. Might
+
<dd><p>当主动开启者的套接字实际建立连接时调用。 例如,可能会发送“欢迎”横幅,或启动与远程端点的协议协商。</p></dd></dl>
send a &quot;welcome&quot; banner, or initiate a protocol negotiation with the
 
remote endpoint, for example.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>handle_close</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">handle_close</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called when the socket is closed.</p></dd></dl>
+
<dd><p>当套接字关闭时调用。</p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>handle_error</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">handle_error</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called when an exception is raised and not otherwise handled. The default
+
<dd><p>在引发异常且未以其他方式处理时调用。 默认版本打印压缩回溯。</p></dd></dl>
version prints a condensed traceback.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>handle_accept</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">handle_accept</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called on listening channels (passive openers) when a connection can be
+
<dd><p>当可以与新的远程端点建立连接时,在侦听通道(被动开启器)上调用,该端点已为本地端点发出 [[#asyncore.dispatcher.connect|connect()]] 调用。 在 3.2 版本中已弃用; 改用 [[#asyncore.dispatcher.handle_accepted|handle_accepted()]]</p>
established with a new remote endpoint that has issued a [[#asyncore.dispatcher.connect|<code>connect()</code>]]
 
call for the local endpoint. Deprecated in version 3.2; use
 
[[#asyncore.dispatcher.handle_accepted|<code>handle_accepted()</code>]] instead.</p>
 
 
<div class="deprecated">
 
<div class="deprecated">
  
<p><span class="versionmodified deprecated">3.2 版后已移除.</span></p>
+
<p><span class="versionmodified deprecated">3.2 版起已弃用。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>handle_accepted</code><span class="sig-paren">(</span>''<span class="n">sock</span>'', ''<span class="n">addr</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">handle_accepted</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">sock</span></span>'', ''<span class="n"><span class="pre">addr</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Called on listening channels (passive openers) when a connection has been
+
<dd><p>当与新的远程端点建立连接时,在侦听通道(被动开启器)上调用,该端点已为本地端点发出 [[#asyncore.dispatcher.connect|connect()]] 调用。 ''sock'' 是一个 ''new'' 套接字对象,可用于在连接上发送和接收数据,''addr'' 是绑定到连接另一端套接字的地址.</p>
established with a new remote endpoint that has issued a [[#asyncore.dispatcher.connect|<code>connect()</code>]]
 
call for the local endpoint. ''sock'' is a ''new'' socket object usable to
 
send and receive data on the connection, and ''addr'' is the address
 
bound to the socket on the other end of the connection.</p>
 
 
<div class="versionadded">
 
<div class="versionadded">
  
<p><span class="versionmodified added">3.2 新版功能.</span></p>
+
<p><span class="versionmodified added">3.2 版中的新功能。</span></p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>readable</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">readable</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called each time around the asynchronous loop to determine whether a
+
<dd><p>每次围绕异步循环调用以确定是否应将通道的套接字添加到可以发生读取事件的列表中。 默认方法简单地返回 <code>True</code>,表示默认情况下,所有通道都会对读取事件感兴趣。</p></dd></dl>
channel's socket should be added to the list on which read events can
 
occur. The default method simply returns <code>True</code>, indicating that by
 
default, all channels will be interested in read events.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>writable</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">writable</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Called each time around the asynchronous loop to determine whether a
+
<dd><p>每次围绕异步循环调用以确定是否应将通道的套接字添加到可以发生写入事件的列表中。 默认方法简单地返回 <code>True</code>,表示默认情况下,所有通道都会对写入事件感兴趣。</p></dd></dl>
channel's socket should be added to the list on which write events can
 
occur. The default method simply returns <code>True</code>, indicating that by
 
default, all channels will be interested in write events.</p></dd></dl>
 
  
<p>In addition, each channel delegates or extends many of the socket methods.
+
<p>此外,每个通道都委托或扩展了许多套接字方法。 其中大多数与它们的套接字伙伴几乎相同。</p>
Most of these are nearly identical to their socket partners.</p>
 
 
<dl>
 
<dl>
<dt><code>create_socket</code><span class="sig-paren">(</span>''<span class="n">family</span><span class="o">=</span><span class="default_value">socket.AF_INET</span>'', ''<span class="n">type</span><span class="o">=</span><span class="default_value">socket.SOCK_STREAM</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">create_socket</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">family</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">socket.AF_INET</span></span>'', ''<span class="n"><span class="pre">type</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">socket.SOCK_STREAM</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>This is identical to the creation of a normal socket, and will use the
+
<dd><p>这与创建普通套接字相同,并且将使用相同的创建选项。 有关创建套接字的信息,请参阅 [[../socket#module-socket|socket]] 文档。</p>
same options for creation. Refer to the [[../socket#module-socket|<code>socket</code>]] documentation for
 
information on creating sockets.</p>
 
 
<div class="versionchanged">
 
<div class="versionchanged">
  
<p><span class="versionmodified changed">3.3 版更改: </span>''family'' and ''type'' arguments can be omitted.</p>
+
<p><span class="versionmodified changed"> 3.3 版更改: </span>''family'' ''type'' 参数可以省略。</p>
  
 
</div></dd></dl>
 
</div></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>connect</code><span class="sig-paren">(</span>''<span class="n">address</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">connect</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">address</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>As with the normal socket object, ''address'' is a tuple with the first
+
<dd><p>与普通的套接字对象一样,''address'' 是一个元组,第一个元素是主机要连接到的元素,第二个元素是端口号。</p></dd></dl>
element the host to connect to, and the second the port number.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>send</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">send</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">data</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Send ''data'' to the remote end-point of the socket.</p></dd></dl>
+
<dd><p>''data'' 发送到套接字的远程端点。</p></dd></dl>
  
 
<dl>
 
<dl>
<dt><code>recv</code><span class="sig-paren">(</span>''<span class="n">buffer_size</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">recv</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">buffer_size</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Read at most ''buffer_size'' bytes from the socket's remote end-point. An
+
<dd><p>从套接字的远程端点最多读取 ''buffer_size'' 个字节。 空字节对象意味着通道已从另一端关闭。</p>
empty bytes object implies that the channel has been closed from the
+
<p>请注意 [[#asyncore.dispatcher.recv|recv()]] 可能会引发 [[../exceptions#BlockingIOError|BlockingIOError]] ,即使 [[../select#select|select.select()]] [[../select#select|select.poll()]] 已报告套接字准备阅读。</p></dd></dl>
other end.</p>
 
<p>Note that [[#asyncore.dispatcher.recv|<code>recv()</code>]] may raise [[../exceptions#BlockingIOError|<code>BlockingIOError</code>]] , even though
 
[[../select#select|<code>select.select()</code>]] or [[../select#select|<code>select.poll()</code>]] has reported the socket
 
ready for reading.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>listen</code><span class="sig-paren">(</span>''<span class="n">backlog</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">listen</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">backlog</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Listen for connections made to the socket. The ''backlog'' argument
+
<dd><p>侦听与套接字的连接。 ''backlog'' 参数指定排队连接的最大数量,并且应该至少为 1; 最大值取决于系统(通常为 5)。</p></dd></dl>
specifies the maximum number of queued connections and should be at least
 
1; the maximum value is system-dependent (usually 5).</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>bind</code><span class="sig-paren">(</span>''<span class="n">address</span>''<span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">bind</span></span><span class="sig-paren">(</span>''<span class="n"><span class="pre">address</span></span>''<span class="sig-paren">)</span></dt>
<dd><p>Bind the socket to ''address''. The socket must not already be bound. (The
+
<dd><p>将套接字绑定到 ''地址'' 。 套接字必须尚未绑定。 (''address'' 的格式取决于地址族 — 有关详细信息,请参阅 [[../socket#module-socket|socket]] 文档。)将套接字标记为可重用(设置 <code>SO_REUSEADDR</code>选项),调用 [[#asyncore.dispatcher|dispatcher]] 对象的 <code>set_reuse_addr()</code> 方法。</p></dd></dl>
format of ''address'' depends on the address family --- refer to the
 
[[../socket#module-socket|<code>socket</code>]] documentation for more information.) To mark
 
the socket as re-usable (setting the <code>SO_REUSEADDR</code> option), call
 
the [[#asyncore.dispatcher|<code>dispatcher</code>]] object's <code>set_reuse_addr()</code> method.</p></dd></dl>
 
  
 
<dl>
 
<dl>
<dt><code>accept</code><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
+
<dt><span class="sig-name descname"><span class="pre">accept</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span></dt>
<dd><p>Accept a connection. The socket must be bound to an address and listening
+
<dd><p>接受连接。 套接字必须绑定到一个地址并侦听连接。 返回值可以是 <code>None</code> 或一对 <code>(conn, address)</code>,其中 ''conn'' 是可用于在连接上发送和接收数据的 ''new'' 套接字对象, ''address'' 是绑定到连接另一端套接字的地址。 当返回 <code>None</code> 时,表示连接没有发生,在这种情况下,服务器应该忽略此事件并继续侦听进一步传入的连接。</p></dd></dl>
for connections. The return value can be either <code>None</code> or a pair
 
<code>(conn, address)</code> where ''conn'' is a ''new'' socket object usable to send
 
and receive data on the connection, and ''address'' is the address bound to
 
the socket on the other end of the connection.
 
When <code>None</code> is returned it means the connection didn't take place, in
 
which case the server should just ignore this event and keep listening
 
for further incoming connections.</p></dd></dl>
 
  
 
<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>Close the socket. All future operations on the socket object will fail.
+
<dd><p>关闭插座。 套接字对象上的所有未来操作都将失败。 远程端点将不再接收数据(在刷新排队数据后)。 套接字在垃圾收集时会自动关闭。</p></dd></dl>
The remote end-point will receive no more data (after queued data is
 
flushed). Sockets are automatically closed when they are
 
garbage-collected.</p></dd></dl>
 
 
</dd></dl>
 
</dd></dl>
  
; ''class'' <code>asyncore.</code><code>dispatcher_with_send</code>
+
; ''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncore.</span></span><span class="sig-name descname"><span class="pre">dispatcher_with_send</span></span>
: A [[#asyncore.dispatcher|<code>dispatcher</code>]] subclass which adds simple buffered output capability, useful for simple clients. For more sophisticated usage use [[../asynchat#asynchat|<code>asynchat.async_chat</code>]].
+
: 一个 [[#asyncore.dispatcher|dispatcher]] 子类,它添加了简单的缓冲输出功能,对简单的客户端很有用。 对于更复杂的用法,请使用 [[../asynchat#asynchat|asynchat.async_chat]]
  
<dl>
+
; ''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncore.</span></span><span class="sig-name descname"><span class="pre">file_dispatcher</span></span>
<dt>''class'' <code>asyncore.</code><code>file_dispatcher</code></dt>
+
: file_dispatcher 接受一个文件描述符或 [[../../glossary#term-file-object|文件对象]] 以及一个可选的映射参数,并将其包装起来以与 <code>poll()</code> <code>loop()</code> 函数一起使用。 如果提供了一个文件对象或任何带有 <code>fileno()</code> 方法的东西,该方法将被调用并传递给 [[#asyncore.file_wrapper|file_wrapper]] 构造函数。
<dd><p>A file_dispatcher takes a file descriptor or [[../../glossary#term-file-object|<span class="xref std std-term">file object</span>]] along
 
with an optional map argument and wraps it for use with the <code>poll()</code>
 
or <code>loop()</code> functions. If provided a file object or anything with a
 
<code>fileno()</code> method, that method will be called and passed to the
 
[[#asyncore.file_wrapper|<code>file_wrapper</code>]] constructor.</p>
 
<p>[[../intro#availability|<span class="std std-ref">Availability</span>]]: Unix.</p></dd></dl>
 
  
<dl>
+
; ''<span class="pre">class</span>'' <span class="sig-prename descclassname"><span class="pre">asyncore.</span></span><span class="sig-name descname"><span class="pre">file_wrapper</span></span>
<dt>''class'' <code>asyncore.</code><code>file_wrapper</code></dt>
+
: file_wrapper 接受一个整数文件描述符并调用 [[../os#os|os.dup()]] 来复制句柄,以便可以独立于 file_wrapper 关闭原始句柄。 此类实现了足够的方法来模拟供 [[#asyncore.file_dispatcher|file_dispatcher]] 类使用的套接字。
<dd><p>A file_wrapper takes an integer file descriptor and calls [[../os#os|<code>os.dup()</code>]] to
 
duplicate the handle so that the original handle may be closed independently
 
of the file_wrapper. This class implements sufficient methods to emulate a
 
socket for use by the [[#asyncore.file_dispatcher|<code>file_dispatcher</code>]] class.</p>
 
<p>[[../intro#availability|<span class="std std-ref">Availability</span>]]: Unix.</p></dd></dl>
 
  
 
<div id="asyncore-example-basic-http-client" class="section">
 
<div id="asyncore-example-basic-http-client" class="section">
  
 
<span id="asyncore-example-1"></span>
 
<span id="asyncore-example-1"></span>
== asyncore Example basic HTTP client ==
+
== asyncore 示例基本 HTTP 客户端 ==
  
Here is a very basic HTTP client that uses the [[#asyncore.dispatcher|<code>dispatcher</code>]] class to
+
这是一个非常基本的 HTTP 客户端,它使用 [[#asyncore.dispatcher|dispatcher]] 类来实现其套接字处理:
implement its socket handling:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第283行: 第180行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncore
+
<syntaxhighlight lang="python3">import asyncore
  
 
class HTTPClient(asyncore.dispatcher):
 
class HTTPClient(asyncore.dispatcher):
第304行: 第201行:
  
 
     def writable(self):
 
     def writable(self):
         return (len(self.buffer) &gt; 0)
+
         return (len(self.buffer) > 0)
  
 
     def handle_write(self):
 
     def handle_write(self):
第312行: 第209行:
  
 
client = HTTPClient('www.python.org', '/')
 
client = HTTPClient('www.python.org', '/')
asyncore.loop()</pre>
+
asyncore.loop()</syntaxhighlight>
  
 
</div>
 
</div>
第322行: 第219行:
  
 
<span id="asyncore-example-2"></span>
 
<span id="asyncore-example-2"></span>
== asyncore Example basic echo server ==
+
== asyncore 示例基本回显服务器 ==
  
Here is a basic echo server that uses the [[#asyncore.dispatcher|<code>dispatcher</code>]] class to accept
+
这是一个基本的回显服务器,它使用 [[#asyncore.dispatcher|dispatcher]] 类来接受连接并将传入的连接分派给处理程序:
connections and dispatches the incoming connections to a handler:
 
  
 
<div class="highlight-python3 notranslate">
 
<div class="highlight-python3 notranslate">
第331行: 第227行:
 
<div class="highlight">
 
<div class="highlight">
  
<pre>import asyncore
+
<syntaxhighlight lang="python3">import asyncore
  
 
class EchoHandler(asyncore.dispatcher_with_send):
 
class EchoHandler(asyncore.dispatcher_with_send):
第354行: 第250行:
  
 
server = EchoServer('localhost', 8080)
 
server = EchoServer('localhost', 8080)
asyncore.loop()</pre>
+
asyncore.loop()</syntaxhighlight>
 +
 
 +
</div>
  
 
</div>
 
</div>
第361行: 第259行:
  
 
</div>
 
</div>
 +
<div class="clearer">
 +
 +
  
 
</div>
 
</div>
  
[[Category:Python 3.9 中文文档]]
+
[[Category:Python 3.9 文档]]

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

asyncore — 异步套接字处理程序

源代码: :source:`Lib/asyncore.py`

自 3.6 版起已弃用:请改用 asyncio



笔记

该模块的存在只是为了向后兼容。 对于新代码,我们建议使用 asyncio


该模块提供了用于编写异步套接字服务客户端和服务器的基本基础结构。

只有两种方法可以让单个处理器上的程序“一次做不止一件事情”。 多线程编程是最简单和最流行的方法,但还有另一种非常不同的技术,它可以让您拥有多线程的几乎所有优点,而无需实际使用多线程。 只有当您的程序在很大程度上受 I/O 限制时,它才真正实用。 如果您的程序受处理器限制,那么抢占式调度线程可能是您真正需要的。 然而,网络服务器很少受处理器限制。

如果您的操作系统在其 I/O 库中支持 [X38X] 系统调用(并且几乎都支持),那么您可以使用它同时处理多个通信通道; 在您的 I/O 在“后台”进行时做其他工作。 尽管这种策略看起来很奇怪和复杂,尤其是一开始,它在很多方面比多线程编程更容易理解和控制。 asyncore 模块为您解决了许多难题,使构建复杂的高性能网络服务器和客户端的任务变得轻而易举。 对于“对话”应用程序和协议,配套的 asynchat 模块是无价的。

这两个模块背后的基本思想是创建一个或多个网络 通道 、类 asyncore.dispatcherasynchat.async_chat 的实例。 创建通道将它们添加到全局地图中,如果您没有提供自己的 地图 ,则由 loop() 函数使用。

一旦创建了初始通道,调用 loop() 函数激活通道服务,该服务一直持续到最后一个通道(包括在异步服务期间添加到地图的任何通道)是关闭。

asyncore.loop([timeout[, use_poll[, map[, count]]]])

进入一个轮询循环,该循环在计数通过或所有打开的通道都已关闭后终止。 所有参数都是可选的。 count 参数默认为 None,导致循环仅在所有通道都已关闭时终止。 timeout 参数为适当的 select()poll() 调用设置超时参数,以秒为单位; 默认值为 30 秒。 use_poll 参数,如果为真,则表示 poll() 应该优先于 select()(默认为 False) .

map 参数是一个字典,其项目是要观看的频道。 当通道关闭时,它们会从它们的地图中删除。 如果省略 map,则使用全局映射。 频道(asyncore.dispatcherasynchat.async_chat 及其子类的实例)可以在地图中自由混合。

class asyncore.dispatcher

dispatcher 类是一个围绕低级套接字对象的瘦包装器。 为了使它更有用,它有一些从异步循环调用的事件处理方法。 否则,它可以被视为一个普通的非阻塞套接字对象。

在某些时间或在某些连接状态下触发低级事件告诉异步循环某些高级事件已经发生。 例如,如果我们要求一个套接字连接到另一台主机,当套接字第一次变为可写时,我们就知道已经建立了连接(此时您知道您可以期望成功写入它) )。 隐含的更高级别的事件是:

事件

说明

handle_connect()

由第一个读或写事件暗示

handle_close()

由没有可用数据的读取事件暗示

handle_accepted()

由侦听套接字上的读取事件暗示

在异步处理过程中,每个映射通道的 readable()writable() 方法用于确定该通道的套接字是否应添加到通道列表 select()ed或 poll()ed 用于读取和写入事件。

因此,通道事件集大于基本套接字事件。 可以在您的子类中覆盖的全套方法如下:

handle_read()

当异步循环检测到通道套接字上的 read() 调用将成功时调用。

handle_write()

当异步循环检测到可以写入可写套接字时调用。 通常,此方法将实现必要的性能缓冲。 例如:

def handle_write(self):
    sent = self.send(self.buffer)
    self.buffer = self.buffer[sent:]
handle_expt()

当套接字连接有带外 (OOB) 数据时调用。 这几乎永远不会发生,因为 OOB 很少被支持并且很少使用。

handle_connect()

当主动开启者的套接字实际建立连接时调用。 例如,可能会发送“欢迎”横幅,或启动与远程端点的协议协商。

handle_close()

当套接字关闭时调用。

handle_error()

在引发异常且未以其他方式处理时调用。 默认版本打印压缩回溯。

handle_accept()

当可以与新的远程端点建立连接时,在侦听通道(被动开启器)上调用,该端点已为本地端点发出 connect() 调用。 在 3.2 版本中已弃用; 改用 handle_accepted()

自 3.2 版起已弃用。

handle_accepted(sock, addr)

当与新的远程端点建立连接时,在侦听通道(被动开启器)上调用,该端点已为本地端点发出 connect() 调用。 sock 是一个 new 套接字对象,可用于在连接上发送和接收数据,addr 是绑定到连接另一端套接字的地址.

3.2 版中的新功能。

readable()

每次围绕异步循环调用以确定是否应将通道的套接字添加到可以发生读取事件的列表中。 默认方法简单地返回 True,表示默认情况下,所有通道都会对读取事件感兴趣。

writable()

每次围绕异步循环调用以确定是否应将通道的套接字添加到可以发生写入事件的列表中。 默认方法简单地返回 True,表示默认情况下,所有通道都会对写入事件感兴趣。

此外,每个通道都委托或扩展了许多套接字方法。 其中大多数与它们的套接字伙伴几乎相同。

create_socket(family=socket.AF_INET, type=socket.SOCK_STREAM)

这与创建普通套接字相同,并且将使用相同的创建选项。 有关创建套接字的信息,请参阅 socket 文档。

3.3 版更改: familytype 参数可以省略。

connect(address)

与普通的套接字对象一样,address 是一个元组,第一个元素是主机要连接到的元素,第二个元素是端口号。

send(data)

data 发送到套接字的远程端点。

recv(buffer_size)

从套接字的远程端点最多读取 buffer_size 个字节。 空字节对象意味着通道已从另一端关闭。

请注意 recv() 可能会引发 BlockingIOError ,即使 select.select()select.poll() 已报告套接字准备阅读。

listen(backlog)

侦听与套接字的连接。 backlog 参数指定排队连接的最大数量,并且应该至少为 1; 最大值取决于系统(通常为 5)。

bind(address)

将套接字绑定到 地址 。 套接字必须尚未绑定。 (address 的格式取决于地址族 — 有关详细信息,请参阅 socket 文档。)将套接字标记为可重用(设置 SO_REUSEADDR选项),调用 dispatcher 对象的 set_reuse_addr() 方法。

accept()

接受连接。 套接字必须绑定到一个地址并侦听连接。 返回值可以是 None 或一对 (conn, address),其中 conn 是可用于在连接上发送和接收数据的 new 套接字对象, address 是绑定到连接另一端套接字的地址。 当返回 None 时,表示连接没有发生,在这种情况下,服务器应该忽略此事件并继续侦听进一步传入的连接。

close()

关闭插座。 套接字对象上的所有未来操作都将失败。 远程端点将不再接收数据(在刷新排队数据后)。 套接字在垃圾收集时会自动关闭。

class asyncore.dispatcher_with_send
一个 dispatcher 子类,它添加了简单的缓冲输出功能,对简单的客户端很有用。 对于更复杂的用法,请使用 asynchat.async_chat
class asyncore.file_dispatcher
file_dispatcher 接受一个文件描述符或 文件对象 以及一个可选的映射参数,并将其包装起来以与 poll()loop() 函数一起使用。 如果提供了一个文件对象或任何带有 fileno() 方法的东西,该方法将被调用并传递给 file_wrapper 构造函数。
class asyncore.file_wrapper
file_wrapper 接受一个整数文件描述符并调用 os.dup() 来复制句柄,以便可以独立于 file_wrapper 关闭原始句柄。 此类实现了足够的方法来模拟供 file_dispatcher 类使用的套接字。

asyncore 示例基本 HTTP 客户端

这是一个非常基本的 HTTP 客户端,它使用 dispatcher 类来实现其套接字处理:

import asyncore

class HTTPClient(asyncore.dispatcher):

    def __init__(self, host, path):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.connect( (host, 80) )
        self.buffer = bytes('GET %s HTTP/1.0\r\nHost: %s\r\n\r\n' %
                            (path, host), 'ascii')

    def handle_connect(self):
        pass

    def handle_close(self):
        self.close()

    def handle_read(self):
        print(self.recv(8192))

    def writable(self):
        return (len(self.buffer) > 0)

    def handle_write(self):
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]


client = HTTPClient('www.python.org', '/')
asyncore.loop()

asyncore 示例基本回显服务器

这是一个基本的回显服务器,它使用 dispatcher 类来接受连接并将传入的连接分派给处理程序:

import asyncore

class EchoHandler(asyncore.dispatcher_with_send):

    def handle_read(self):
        data = self.recv(8192)
        if data:
            self.send(data)

class EchoServer(asyncore.dispatcher):

    def __init__(self, host, port):
        asyncore.dispatcher.__init__(self)
        self.create_socket()
        self.set_reuse_addr()
        self.bind((host, port))
        self.listen(5)

    def handle_accepted(self, sock, addr):
        print('Incoming connection from %s' % repr(addr))
        handler = EchoHandler(sock)

server = EchoServer('localhost', 8080)
asyncore.loop()