asyncore 未运行handle_read
我试图制作一个简单的异步示例,其中一个套接字是发送者,一个是接收者。由于某种原因,接收器上的handle_read()永远不会被调用,所以我永远不会得到“测试”数据。有人知道为什么吗?这是我第一次尝试 asyncore,所以它可能非常简单。
import asyncore, socket, pdb, random
class Sender(asyncore.dispatcher):
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
def handle_connect(self):
print ('first connect')
def writable(self):
True
def readable(self):
return False
def handle_write(self):
pass
def handle_close(self):
self.close()
class Receiver(asyncore.dispatcher):
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
def handle_connect(self):
print ('first connect')
def readable(self):
return True
def handle_read(self):
print 'reading'
def handle_write(self):
print 'write'
def handle_accept(self):
self.conn_sock, addr = self.accept()
print 'accepted'
def handle_close(self):
self.close()
a = Sender()
b = Receiver()
addr = ('localhost', 12344)
b.bind(addr)
b.listen(1)
a.connect(addr)
asyncore.loop()
a.send('test')
I'm trying to just make a simple asyncore example where one socket is the sender and one is the receiver. For some reason, the handle_read() on the receiver is never called so I never get the 'test' data. Anyone know why? This is my first shot at asyncore, so it's probably something extremely simple.
import asyncore, socket, pdb, random
class Sender(asyncore.dispatcher):
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
def handle_connect(self):
print ('first connect')
def writable(self):
True
def readable(self):
return False
def handle_write(self):
pass
def handle_close(self):
self.close()
class Receiver(asyncore.dispatcher):
def __init__(self):
asyncore.dispatcher.__init__(self)
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
def handle_connect(self):
print ('first connect')
def readable(self):
return True
def handle_read(self):
print 'reading'
def handle_write(self):
print 'write'
def handle_accept(self):
self.conn_sock, addr = self.accept()
print 'accepted'
def handle_close(self):
self.close()
a = Sender()
b = Receiver()
addr = ('localhost', 12344)
b.bind(addr)
b.listen(1)
a.connect(addr)
asyncore.loop()
a.send('test')
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
asyncore.loop
不会终止,因此a.send
不会发生,因为您已将其编码为在之后行中发生asyncore.loop 退出。一旦解决了这个问题,您就会遇到在单个线程和进程中运行发送方和接收方的问题,因此除非您采取非常微妙的步骤来确保一切都按正确的顺序发生,否则您将陷入僵局。 asyncore 当然是为了在单独运行的进程之间使用,所以这个问题在正常的实际使用中不会出现。如果您对死锁的确切位置感到好奇,请制作自己的 asyncore 副本并在其中添加 print 语句,或者尝试
不幸的是,后者给出了很多输出并且不显示关键变量的值。因此,虽然尝试起来很轻松且非侵入性,但它的帮助远不如一些战略性放置的 print (例如,每次选择之前和之后的 r 和 w fd 列表)。
我相信(但没有深入调试它,因为无论如何这是一个不切实际的场景)选择仅触发一次(因为您同时接受/连接和向套接字写入字节的情况发生)在第一次选择之前,它们最终“折叠”成一个事件),但是该事件的处理无法知道折叠(正常使用中不会发生!-),因此它只处理接受/连接。但如果您花时间进行更深入的调试,您无疑会更好地理解这种异常情况!
asyncore.loop
does not terminate, so thea.send
doesn't happen, since you've coded it to happen in line after the exit of asyncore.loop.Once this is fixed, you run into the problem that you're running sender and receiver within a single thread and process, so unless you take very delicate steps to ensure everything happens in the right order, you ARE going to get deadlocked. asyncore is of course meant to be used among processes running separately, so the problem just doesn't appear in normal, real-world uses. If you're curious about exactly where you're deadlocking, make your own copy of asyncore and pepper it with print statements, or, try
Unfortunately, the latter gives a lot of output and doesn't show crucial variables' values. so, while painless and non-invasive to try, it's far less helpful than a few strategically placed
print
s (e.g., the r and w fd lists just before and after each select).I believe (but haven't debugged it in depth, since it's an unrealistic scenario anyway) that the select triggers only once (because you have both the accept/connect and the writing of bytes to the socket happen before the first select, they end up "collapsed" into a single event), but the handling of that one event can't know about the collapsing (wouldn't happen in normal use!-) so it only deals with the accept/connect. But if you take the time to debug in greater depth you may no doubt understand this anomalous scenario better!
很晚了,没有解决问题,因为亚历克斯指出了原因,但你的代码显示:
不应该是:
A lot late and not solving the issue as Alex points to the causes, but your code shows:
Shouldn't that be: