You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

O365 SMTP连接异常:后续连接遭主动拒绝问题排查

解决方案

核心问题:复用SMTP实例导致状态异常

你遇到的问题本质是重复使用同一个SMTP对象引发的状态混乱。smtplib的SMTP实例是有状态的,第一次发送后实例已处于断开/失效状态,复用会触发错误;手动调用connect()则大概率是协议或端口参数不匹配,导致被服务器主动拒绝。

正确实现方式:每次请求创建全新SMTP连接

鉴于你的请求频率极低(每周5次),完全不需要长连接,每次处理Webhook请求时创建全新SMTP实例即可,具体步骤如下:

  1. 匹配邮件服务器的SMTP类与端口:

    • 若服务器要求SSL加密(如Gmail的465端口),使用smtplib.SMTP_SSL()
    • 若采用STARTTLS加密(多数服务商的587端口),使用smtplib.SMTP()并在连接后调用starttls()
  2. 每次请求内完整执行「连接→认证→发送→断开」流程,代码示例:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:55:17