0

我正在尝试制作一个简单的异步示例,其中一个套接字是发送者,一个是接收者。出于某种原因,接收器上的 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')
4

2 回答 2

1

asyncore.loop不会终止,因此a.send不会发生,因为您已将其编码为在asyncore.loop 退出后在线发生。

一旦解决了这个问题,您就会遇到在单个线程和进程中运行发送方和接收方的问题,因此除非您采取非常精细的步骤来确保一切都以正确的顺序发生,否则您将陷入僵局。asyncore 当然是在单独运行的进程之间使用的,所以这个问题不会出现在正常的实际使用中。如果您对死锁的确切位置感到好奇,请制作自己的 asyncore 副本并在其中添加 print 语句,或者尝试

python -m trace -t ast.py

不幸的是,后者提供了很多输出并且没有显示关键变量的值。因此,虽然尝试起来无痛且无创,但它远不如几个战略性放置print的 s 有用(例如,在每次选择之前和之后的 r 和 w fd 列表)。

我相信(但还没有深入调试它,因为无论如何这是一个不切实际的场景)选择只触发一次(因为你有接受/连接字节写入套接字都发生在第一次选择之前,它们结束向上“折叠”成单个事件),但该事件的处理无法知道折叠(在正常使用中不会发生!-)所以它只处理接受/连接。但是,如果您花时间进行更深入的调试,无疑您可能会更好地理解这种异常情况!

于 2009-10-17T16:18:42.933 回答
1

很晚了,并且没有解决问题,因为 Alex 指出了原因,但是您的代码显示:

def writable(self):
     True 

那不应该是:

def writable(self):
     return True 
于 2012-06-27T12:46:51.413 回答