O365 SMTP连接异常:后续连接遭主动拒绝问题排查
解决方案
核心问题:复用SMTP实例导致状态异常
你遇到的问题本质是重复使用同一个SMTP对象引发的状态混乱。smtplib的SMTP实例是有状态的,第一次发送后实例已处于断开/失效状态,复用会触发错误;手动调用connect()则大概率是协议或端口参数不匹配,导致被服务器主动拒绝。
正确实现方式:每次请求创建全新SMTP连接
鉴于你的请求频率极低(每周5次),完全不需要长连接,每次处理Webhook请求时创建全新SMTP实例即可,具体步骤如下:
匹配邮件服务器的SMTP类与端口:
- 若服务器要求SSL加密(如Gmail的465端口),使用
smtplib.SMTP_SSL() - 若采用STARTTLS加密(多数服务商的587端口),使用
smtplib.SMTP()并在连接后调用starttls()
- 若服务器要求SSL加密(如Gmail的465端口),使用
每次请求内完整执行「连接→认证→发送→断开」流程,代码示例:
from flask import Flask, request import smtplib from email.mime.text import MIMEText app = Flask(__name__) # 邮件配置 SMTP_SERVER = "你的SMTP服务器地址" SMTP_PORT = 587 # 或465,根据服务器要求调整 SMTP_USER = "你的邮箱账号" SMTP_PASS = "你的邮箱密码/应用专用密码" @app.route('/webhook', methods=['POST']) def handle_webhook(): # 解析请求负载 payload = request.json email_content = f"收到Webhook请求:{payload}" # 构建邮件内容 msg = MIMEText(email_content) msg['Subject'] = "Webhook通知" msg['From'] = SMTP_USER msg['To'] = "收件人邮箱地址" # 每次请求创建全新SMTP连接 try: # 根据端口选择对应SMTP类 if SMTP_PORT == 465: server = smtplib.SMTP_SSL(SMTP_SERVER, SMTP_PORT) else: server = smtplib.SMTP(SMTP_SERVER, SMTP_PORT) server.starttls() # 启用STARTTLS加密 server.login(SMTP_USER, SMTP_PASS) server.send_message(msg) server.quit() # 发送QUIT命令后断开,确保服务器释放资源 return "邮件发送成功", 200 except Exception as e: return f"发送失败:{str(e)}", 500 if __name__ == '__main__': app.run(port=5000)
关键注意事项
- 禁止复用SMTP实例:每次请求新建实例,彻底避免状态残留问题
- 端口与协议必须匹配:WinError 10061多因端口错误或协议不匹配(比如用普通SMTP连接465端口,应改用SMTP_SSL)
- 无需手动调用connect():
SMTP()或SMTP_SSL()初始化时会自动执行连接,手动调用反而可能引发重复连接错误 - 优先用quit()而非close():
quit()会先向服务器发送QUIT命令再关闭连接,确保服务器端正确释放资源
内容的提问来源于stack exchange,提问作者AV Man
相关产品推荐
相关产品推荐

