如何在Python的smtplib中保持SMTP连接开放?

3 投票
3 回答
8157 浏览
提问于 2025-04-16 05:47

我需要检查一个SMTP服务器的超时时间,但我的套接字(socket)直接关闭了。我到底哪里做错了呢?这是我用来测试的代码:

#!/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

希望这个能成功。

3 个回答

0

检查一下你的邮件服务器设置,可能是它在断开连接。

1

你确定你已经断开连接了吗?当我用上面的代码去连接一个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]
10

嗯,我还没有找到用smtplib保持SMTP连接的方法。

不过,如果你想在不关闭连接的情况下重复使用它(是的,打开一个连接需要时间,大约2-3秒),你可以先测试一下连接。方法是发一个NOOP命令,然后检查状态是否为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

撰写回答