带有asyncore的SMTPServer是否打开套接字?

时间:2018-01-18 11:03:00

标签: python sockets smtplib asyncore

我已经实现了一个基本的SMTP服务器,它运行良好,但我遇到了一个问题而且我不知道如何解决它。

检查为运行我的脚本(ls -l /proc/$PID/fd/ | grep "socket:" | wc -l)的进程的$ PID打开的文件描述符时,文件描述符的数量不断增加。

由于我使用" socket过滤:",显然有些套接字保持打开状态,当然是因为某些邮件提供商没有明确退出。

我在本地测试了一些连接到SMTPServer代码的Python脚本,即使我没有关闭连接,当客户端进程停止时,客户端关闭连接,并且文件描述符已删除。

我考虑过实现等待的超时,或者每N个连接重新启动一个进程,但这些只是解决更大问题的坏补丁。

你知道那会来自哪里吗?

有关信息,我的process_message包装器被

包围
try:
    # ...
except:
    return '450 Please try again later"

因此,应该很好地处理来自我的代码的异常。

这是我的代码(简化):

class MyMXServer(SMTPServer):
    def __init__(self, host='127.0.0.1', port=25):
        self.srs = SRS.new(os.getenv('SRS_KEY', 'some passwd'))
        return SMTPServer.__init__(self, (host, port), None)

    def process_message(self, greeting, peer, mailfrom, recipients, data, **kwargs):
        try:
            return self._process_message(greeting, peer, mailfrom, recipients, data, **kwargs)
        except:
            logging.getLogger('err').exception('[EXCEPTION]')
            return '450 Please try again later.'

    def _process_message(self, greeting, peer, mailfrom, recipients, data, **kwargs):
        # Various things like checking DNSBL, SPF, Spam, etc

1 个答案:

答案 0 :(得分:0)

如果没有看到您的代码,很难回答。但是,您已经实现了异常处理的初始组件。 else可能没有必要,但听起来像finally条款是这种情况下的要求。完成块以确保套接字已关闭:

try:
    # unreliable process
except:
    return '450 Please try again later"
else:
    # successful outcome
finallY:
    socket.close()