如何使用smtplib和Python保持SMTP连接打开?

如何使用smtplib和Python保持SMTP连接打开?,python,sockets,smtp,smtplib,Python,Sockets,Smtp,Smtplib,我需要检查SMTP服务器的超时,但我的套接字刚刚关闭。我做错了什么?以下是我对它的测试: #!/usr/bin/python import smtplib import time import datetime import socket socket.setdefaulttimeout(1800) now = time.time() server = smtplib.SMTP() server.set_debuglevel(1) server.connect('mx.foo.bar','2

我需要检查SMTP服务器的超时,但我的套接字刚刚关闭。我做错了什么?以下是我对它的测试:

#!/usr/bin/python
import smtplib
import time
import datetime
import socket
socket.setdefaulttimeout(1800)


now = time.time()
server = smtplib.SMTP()
server.set_debuglevel(1)
server.connect('mx.foo.bar','25')
(code,resp) = server.docmd('NOOP')
then = time.time()

print then-now

希望这能起作用。

检查您的邮件服务器设置-他们可能正在切断连接。

您确定要断开连接吗?在postfix服务器上运行上述代码时,我得到:

connect: ('server', '25')
connect: ('ip.address', 25)
reply: '220 server ESMTP Postfix\r\n'
reply: retcode (220); Msg: nserver ESMTP Postfix
connect: server ESMTP Postfix
send: 'NOOP\r\n'
reply: '250 2.0.0 Ok\r\n'
reply: retcode (250); Msg: 2.0.0 Ok
0.0531799793243
docmd不阻塞,服务器响应,程序退出。因此,当程序退出时,我断开连接

如果打开python命令行并执行以下操作:

>> import smtplib
>> server = smtplib.SMTP()
>> server.connect('server')
>> server.docmd('NOOP')
(250, '2.0.0 Ok')
>> ## let it sit for 5 minutes
>> server.docmd('NOOP')
(421, '4.4.2 server Error: timeout exceeded')
我的日志证实了这一点:

Oct 20 10:45:35 [postfix/smtpd] connect from unknown[ip.address]
Oct 20 10:50:10 [postfix/smtpd] timeout after NOOP from unknown[ip.address]

嗯,我还没有找到任何方法来保持smtplib打开的smtp连接

但是,如果您想在不关闭(是的,打开)的情况下重用连接 连接需要时间(2-3秒),您可以先测试连接。 为此,发出NOOP命令并测试status==250。如果没有,那么你 可以打开连接并发送邮件。您可以选择在完成之前不退出连接()

import smtplib

def create_conn():
    conn = smtplib.SMTP('smtp.gmail.com', 587)
    ...
    return conn

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

我查过的每一个MTA都是这样。他们得到命令,返回220,然后连接关闭。使用telnet 5分钟后我会超时。为什么要这样做?你连接,你发送邮件,你断开连接。如果不使用连接,为什么要保持连接打开?我正在检查RFC合规性。建议使用Python,而不是C,因为它易于使用。@Ethan-有道理@特雷克斯,谢谢。它工作得很好,在过去的2年多里,我一直在成功地使用它,没有任何问题。这是一种阻塞方法。是否有超时?这可以正常工作,创建一个全局变量smtp\U connection,并在Create\u conn函数中检查Is\u connected(smtp\U connection),它将重复使用相同的连接,直到其关闭或超时。