asyncore.loop 不会在不再连接时终止



我按照一些示例代码在这里使用asyncore,只为asyncore.loop设置了一个timeout值,如以下完整示例所示:

import smtpd
import asyncore
class CustomSMTPServer(smtpd.SMTPServer):
    def process_message(self, peer, mailfrom, rcpttos, data):
        print 'Receiving message from:', peer
        print 'Message addressed from:', mailfrom
        print 'Message addressed to  :', rcpttos
        print 'Message length        :', len(data)
        return
server = CustomSMTPServer(('127.0.0.1', 1025), None)
asyncore.loop(timeout = 1)

我预计 1 秒后会发生超时,但事实并非如此。代码运行的时间要长得多,超过一秒。我在这里错过了什么?

asyncore.loop() timeout参数是select.select调用等待数据的时间量。如果在timeout用完之前没有数据,它将循环并再次调用select.select

channels的想法也是如此。这并不意味着打开套接字,而是表示活动asyncore.dispatcherasynchat.async_chat实例。如果要停止循环,则必须在所有注册的实例上调用 close() 方法。

在您的情况下server.close()将关闭实例/通道并将其从asyncore循环中删除。如果没有更多通道处于活动状态,则此循环将自行终止。

我真的不知道asyncore.loop()timeout参数是否真的是为了在指定时间后使函数调用asyncore.loop()超时,但这里有一个收据,使该函数在指定时间后超时(在示例代码中用asyncore.loop()替换该行):

import signal
class TimeoutError(Exception): pass
# define the timeout handler
def handler(signum, frame):
    raise TimeoutError()
# set the timeout handler and the signal duration
signal.signal(signal.SIGALRM, handler)
signal.alarm(1)
try:
    asyncore.loop()
except TimeoutError as exc:
    print "timeout"
finally:
    signal.alarm(0)

asyncore.loop() 的超时是 select() 的超时。

它没有用,因为当 select() 超时时,它会循环回来,请参阅伪代码:

while True:
    do_something()
    select(...)
    do_something_else()

如果我使用防火墙套接字进行模拟,在我的 Python 2.7.3 asyncore.loop() 中,在某个套接字没有收到数据后 1 分钟超时。

我发现在asyncore.dispatcher"子类"中使用以下方法非常有用:

def handle_error(self):
    raise

通过这种方式,我有"适当的"异常转储。

因为我不想有例外,后来我把它改成这样:

def handle_error(self):
    print "Error downloading %s" % self.host
    pass

现在我的代码工作正常,无一例外。

我没有找到控制超时的方法。

最新更新