有两个文件:server.py和client.py,都是在asyncore.dispatcher的帮助下编写的
服务器.py
import asyncore, socket
class Server(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.bind(('', port))
self.listen(1)
print "Waiting for connection..."
def handle_accept(self):
socket, address = self.accept()
print 'Connection by', address
socket.send("Hello Server")
def handle_read(self):
print "Reading..."
out_buffer = self.recv(1024)
if not out_buffer:
self.close()
print out_buffer
def handle_closed(self):
print "Server: Connection Closed"
self.close()
s = Server('0.0.0.0', 5007)
asyncore.loop()
客户端.py
import asyncore, socket
class Client(asyncore.dispatcher):
def __init__(self, host, port):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.connect((host, port))
print "Client Start..."
def handle_close(self):
print "Client: Connection Closed"
self.close()
def handle_read(self):
data = self.recv(1024)
if data:
print "Received ", data
self.send("Hello Client")
c = Client('127.0.0.1', 5007)
asyncore.loop()
结果:
执行server.py
:
Waiting for connection...
那么client.py
:
Client Start...
Received Hello Server
Client: Connection Closed
Client: Connection Closed
最后client.py退出,在server.py的输出窗口中又显示了一行,服务器继续运行:
Connection by ('127.0.0.1', 58197)
有些事情我无法理解:
为什么client.py中的函数handle_closed
要执行两次?
为什么在server.py中的函数handle_reading
没有执行?client.py已发送消息(“Hello client”),但服务器为什么不能接收它?
为什么在server.py中的函数handle_closed
没有执行?我想在客户机退出时在server.py中执行一些代码,但它似乎与在server.py中执行无关?
我今天也有类似的问题。HealLeHelp类运行两次,因为Read函数返回一组空白数据,然后导致HeleLyWrad触发,当HydLyWrad看到空白数据时,它第二次关闭请求。
如上所述,您需要将handle_read和handle_write函数分离为一个单独的“handler”类。然后,检查缓冲区中是否有空白数据,如果数据为空白,则返回。
在下面的代码中,我将添加每个请求的请求长度。所以,我先拉这个来得到缓冲区的大小。如果为空,则函数返回
异步通话
永远不会调用server.py中的
handle_read()
。但为什么?!这是一个服务器类。。。
是的,但是
Server
类使用它的套接字来监听任何未建立的连接。它上的任何读取都会转到handle_accept()
,在这里,实际的通道套接字(连接到某个端点)应该被赋予某些dispatcher
继承类的新实例(最好)。在Server
的handle_accept()
方法中,由accept()
获得的套接字是本地的,因此在退出此函数时将其删除,因此:接受新连接,发送文本,然后立即终止套接字。阅读异步模块和my answer中的其他问题。
服务器
如我所说,您需要在server.py中为连接创建新类:
注意,当收到空值时,读取不需要手动关闭套接字-
asyncore
会正确关闭连接。当建立连接时,您必须在
Server
中实例化它:您还在
Server
中犯了拼写错误-方法的正确名称是handle_close
。尽管这没用。与客户端连接相关的所有内容都在ClientHandler
中。客户
在client.py中,只需修改
handle_read()
:更改为:
为什么?如果没有这个,
send()
将被调用,即使套接字实际上是关闭的,这将导致handle_close()
被asyncore
第二次调用。就像我说的-asyncore
处理这个。注释
现在您可以为连接编写更复杂的服务器端类。您还可以学习操作系统级套接字的工作方式,这样就不会遇到麻烦。
asyncore
本身是一个很好的套接字包装器,但是如果您想在某些事件驱动环境中执行更高级别的操作,比如HTTP或SMTP处理,那么Twisted库会让您感兴趣!要使
handle_read()
工作,您应该定义readable()
函数。此函数必须返回True
或False
。我认为将此函数添加到代码中可以解决问题:有关一些示例和更多详细信息,请访问此链接:https://parijatmishra.wordpress.com/2008/01/04/writing-a-server-with-pythons-asyncore-module/
相关问题 更多 >
编程相关推荐