开发者

asyncore not running handle_read

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 prints (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 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜