asyncore 未运行 handle_read

0 投票
2 回答
1250 浏览
提问于 2025-04-15 15:08

我正在尝试做一个简单的 asyncore 示例,其中一个套接字是发送者,另一个是接收者。奇怪的是,接收者的 handle_read() 方法从来没有被调用,所以我始终收不到 'test' 数据。有人知道这是为什么吗?这是我第一次接触 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')

2 个回答

1

虽然这个问题已经讨论得很晚了,也没有解决问题,正如Alex所指出的原因,但你的代码显示:

def writable(self):
     True 

那应该是:

def writable(self):
     return True 
1

asyncore.loop 这个东西不会自动结束,所以你写的 a.send 这个发送操作不会执行,因为你把它放在了 asyncore.loop 结束之后的代码里。

一旦这个问题解决了,你会发现另一个麻烦:你把发送和接收都放在了同一个线程和进程里,所以如果你不小心安排好它们的执行顺序,就会出现死锁的情况。其实,asyncore 是设计用来在不同的进程之间工作的,所以在正常情况下,这个问题是不会出现的。如果你想知道到底是哪里出现了死锁,可以自己复制一份 asyncore,然后在里面加一些打印语句,或者试试

python -m trace -t ast.py

不过,后者会输出很多信息,而且不会显示一些关键变量的值。所以虽然尝试起来简单且不麻烦,但比起在几个关键地方加 print 语句(比如在每次选择之前和之后的读写文件描述符列表),帮助就小多了。

我认为(虽然我没有深入调试,因为这个场景本身就不太现实)select 这个操作只会触发一次(因为在第一次 select 之前,你已经同时进行了接受连接和向套接字写入数据的操作,它们最终会“合并”成一个事件),但处理这个事件的代码并不知道这些操作是合并的(在正常使用中是不会发生的!),所以它只处理接受连接的部分。不过,如果你花时间深入调试,肯定能更好地理解这个异常情况!

撰写回答