0

我正在按照一些示例代码在asyncore 此处使用,仅在以下完整示例中设置了一个timeout值:asyncore.loop

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 秒后会发生超时,但事实并非如此。代码运行时间超过一秒。我在这里想念什么?

4

3 回答 3

2

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

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

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

于 2013-01-23T17:29:53.427 回答
1

我真的不知道timeout参数是否asyncore.loop()真的意味着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)
于 2013-01-23T17:30:33.890 回答
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

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

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

于 2013-04-03T22:07:18.157 回答