<h2>异步通话</h2>
<p>永远不会调用server.py中的<code>handle_read()</code>。</p>
<p>但为什么?!这是一个服务器类。。。</em></p>
<p>是的,但是<code>Server</code>类使用它的套接字来监听任何未建立的连接。它上的任何读取都会转到<code>handle_accept()</code>,在这里,实际的通道套接字(连接到某个端点)应该被赋予某些<code>dispatcher</code>继承类的新实例(最好)。在<code>Server</code>的<code>handle_accept()</code>方法中,由<code>accept()</code>获得的套接字是本地的,因此在退出此函数时将其删除,因此:接受新连接,发送文本,然后立即终止套接字。</p>
<p>阅读异步模块和<a href="https://stackoverflow.com/a/18026873/2643692">my answer</a>中的其他问题。</p>
<h3>服务器</h3>
<p>如我所说,您需要在server.py中为连接创建新类:</p>
<pre><code>class ClientHandler(asyncore.dispatcher):
def handle_read(self):
data = self.recv(1024)
if not data:
return
print "Received:", data
def handle_close(self):
print "Server: Connection Closed"
self.close()
</code></pre>
<p>注意,当收到空值时,读取不需要手动关闭套接字-<code>asyncore</code>会正确关闭连接。</p>
<p>当建立连接时,您必须在<code>Server</code>中实例化它:</p>
<pre><code> def handle_accept(self):
...
ClientHandler(socket)
</code></pre>
<p>您还在<code>Server</code>中犯了拼写错误-方法的正确名称是<code>handle_close</code>。尽管这没用。与客户端连接相关的所有内容都在<code>ClientHandler</code>中。</p>
<h3>客户</h3>
<p>在client.py中,只需修改<code>handle_read()</code>:</p>
<pre><code> if data:
print "Received ", data
</code></pre>
<p>更改为:</p>
<pre><code> if not data:
return
print "Received ", data
</code></pre>
<p>为什么?如果没有这个,<code>send()</code>将被调用,即使套接字实际上是关闭的,这将导致<code>handle_close()</code>被<code>asyncore</code>第二次调用。就像我说的-<code>asyncore</code>处理这个。</p>
<h2>注释</h2>
<p>现在您可以为连接编写更复杂的服务器端类。您还可以学习操作系统级套接字的工作方式,这样就不会遇到麻烦。</p>
<p><code>asyncore</code>本身是一个很好的套接字包装器,但是如果您想在某些事件驱动环境中执行更高级别的操作,比如HTTP或SMTP处理,那么<a href="http://twistedmatrix.com/trac/" rel="nofollow noreferrer">Twisted</a>库会让您感兴趣!</p>