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')
asyncore.loop
does not terminate, so the a.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
python -m trace -t ast.py
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:
def writable(self):
True
Shouldn't that be:
def writable(self):
return True
精彩评论