12

我正在使用smtplib并且我正在从我的应用程序发送通知电子邮件。但是我注意到有时(尤其是当邮件发送之间有很多空闲时间时)我会收到SMTPServerDisconnected错误消息。

我想有两种解决方案(不过,一个都不知道)

  1. 增加发送邮件之间的空闲时间
  2. 连接断开时重新连接。

我认为第二种解决方案似乎更优雅。但我该怎么做呢?

编辑:我正在添加代码

from smtplib import SMTP
smtp = SMTP()
smtp.connect('smtp.server.com')
smtp.login('username','password')

def notifyUser():
    smtp.sendmail(from_email, to_email, msg.as_string())
4

2 回答 2

15

是的,您可以检查连接是否打开。为此,请发出 NOOP 命令并测试状态 == 250。如果不是,则在发送邮件之前打开连接。

def test_conn_open(conn):
    try:
        status = conn.noop()[0]
    except:  # smtplib.SMTPServerDisconnected
        status = -1
    return True if status == 250 else False

def send_email(conn, from_email, to_email, msg):
   if not test_conn_open(conn):
       conn = create_conn()
   conn.sendmail(from_email, to_email, msg.as_string())
   return conn    # as you want are trying to reuse it.

请注意,您这样做是因为打开连接(例如使用 gmail)会消耗时间,例如 2-3 秒。随后,为了优化发送您手头可能有的多封电子邮件,您还应该关注 Pedro 的回复(最后一部分)。

于 2013-02-03T23:11:41.970 回答
9

如果您的用例一次发送一条消息,对我来说最正确的解决方案是为每条消息创建一个新的 SMTP 会话:

from smtplib import SMTP

smtp = SMTP('smtp.server.com')

def notifyUser(smtp, smtp_user, smtp_password, from_email, to_email, msg):
    smtp.login(smtp_user, smtp_password)
    smtp.sendmail(from_email, to_email, msg.as_string())
    smtp.quit()

如果您的 SMTP 服务器不需要您对自己进行身份验证(常见情况),则可以进一步简化为:

from smtplib import SMTP

smtp = SMTP('smtp.server.com')

def notifyUser(smtp, from_email, to_email, msg):
    smtp.sendmail(from_email, to_email, msg.as_string())
    smtp.quit()

如果一次发送多条消息是很常见的,并且您希望通过为一组消息重用相同的 SMTP 会话来优化这种情况(如果您不需要登录到 SMTP,可以如上简化服务器):

from smtplib import SMTP

smtp = SMTP('smtp.server.com')

def notifyUsers(smtp, smtp_user, smtp_password, from_to_msgs):
    """
    :param from_to_msgs: iterable of tuples with `(from_email, to_email, msg)`
    """
    smtp.login(smtp_user, smtp_password)
    for from_email, to_email, msg in from_to_msgs:
        smtp.sendmail(from_email, to_email, msg.as_string())
    smtp.quit()
于 2012-09-23T18:47:54.473 回答