Python 2:SMTPServerDisconnected:连接意外关闭

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17759860/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:07:48  来源:igfitidea点击:

Python 2: SMTPServerDisconnected: Connection unexpectedly closed

pythonpython-2.7emailsmtp

提问by Michael

I have a small problem with sending an email in Python:

我在用 Python 发送电子邮件时遇到了一个小问题:

#me == my email address
#you == recipient's email address
me = "[email protected]"
you = "[email protected]"

# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = "Alert"
msg['From'] = me
msg['To'] = you

# Create the body of the message (a plain-text and an HTML version).
html = '<html><body><p>Hi, I have the following alerts for you!</p></body></html>'

# Record the MIME types of both parts - text/plain and text/html.
part2 = MIMEText(html, 'html')

# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part2)

# Send the message via local SMTP server.
s = smtplib.SMTP('aspmx.l.google.com')
# sendmail function takes 3 arguments: sender's address, recipient's address
# and message to send - here it is sent as one string.
s.sendmail(me, you, msg.as_string())
s.quit()

So before now, my program didn't give me an error, but it also didn't send me an email. And now python gives me an error:

所以在此之前,我的程序没有给我一个错误,但它也没有给我发送电子邮件。现在python给了我一个错误:

SMTPServerDisconnected: Connection unexpectedly closed

How can I fix this?

我怎样才能解决这个问题?

回答by Todor Minakov

TLDR: switch to authenticated connection over TLS.

TLDR:切换到通过 TLS 进行身份验证的连接。

Most probably the gmail server rejected the connection after the data command (very nasty of them to do so at this stage :). The actual message is most probably this one:

很可能 gmail 服务器在 data 命令之后拒绝了连接(在这个阶段他们这样做非常讨厌:)。实际消息很可能是这样的:

    retcode (421); Msg: 4.7.0 [ip.octets.listed.here      15] Our system has detected an unusual rate of
    4.7.0 unsolicited mail originating from your IP address. To protect our
    4.7.0 users from spam, mail sent from your IP address has been temporarily
    4.7.0 rate limited. Please visit
    4.7.0  https://support.google.com/mail/answer/81126 to review our Bulk Email
    4.7.0 Senders Guidelines. qa9si9093954wjc.138 - gsmtp

How do I know that? Because I've tried it :) with the s.set_debuglevel(1), which prints the SMTP conversation and you can see firsthand what's the issue.

我怎么知道?因为我已经尝试过 :) s.set_debuglevel(1),它会打印 SMTP 对话,您可以直接看到问题所在。

You've got two options here:

你有两个选择:

  1. Continue using that relay; as explained by Google, it's unencrypted gmail-to-gmail only, and you have to un-blacklist your ip through their procedure

  2. The most fool-proof option is to switch to TLS with authentication

  1. 继续使用那个继电器;正如 Google 所解释的,它只是未加密的 gmail 到 gmail,您必须通过他们的程序将您的 ip 加入黑名单

  2. 最万无一失的选择是切换到带身份验证的 TLS

Here's how the changed source looks like:

以下是更改后的源代码的样子:

# skipped your comments for readability
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

me = "[email protected]"
my_password = r"your_actual_password"
you = "[email protected]"

msg = MIMEMultipart('alternative')
msg['Subject'] = "Alert"
msg['From'] = me
msg['To'] = you

html = '<html><body><p>Hi, I have the following alerts for you!</p></body></html>'
part2 = MIMEText(html, 'html')

msg.attach(part2)

# Send the message via gmail's regular server, over SSL - passwords are being sent, afterall
s = smtplib.SMTP_SSL('smtp.gmail.com')
# uncomment if interested in the actual smtp conversation
# s.set_debuglevel(1)
# do the smtp auth; sends ehlo if it hasn't been sent already
s.login(me, my_password)

s.sendmail(me, you, msg.as_string())
s.quit()

Now, if try to 'cheat' the system and send with a different (non-gmail) address it's gonna a) require you to connect to a different hostname (some of the MX records for gmail), then b) stop you and close the connection on the grounds of blacklisted ip, and c) do reverse DNS, DKIM and lots of other countermeasures to make sure you're actually in control of the domain you presented in the MAIL FROM: address.

现在,如果尝试“欺骗”系统并使用不同的(非 gmail)地址发送,它将 a) 要求您连接到不同的主机名(gmail 的一些 MX 记录),然后 b) 阻止您并关闭以列入黑名单的 ip 为由建立连接,并且 c) 执行反向 DNS、DKIM 和许多其他对策,以确保您实际上控制了您在 MAIL FROM: 地址中显示的域。

Finally, there's also option 3) - use any other email relaying service, there are tons of good ones :)

最后,还有选项 3) - 使用任何其他电子邮件中继服务,有很多好的 :)

回答by Tiwtiw

I Had the same issue and solved it just by specifying the right port like this:

我遇到了同样的问题,只需像这样指定正确的端口就可以解决它:

smtplib.SMTP('smtp.gmail.com', 587)

回答by Nurul Akter Towhid

Using smtplib.SMTP_SSL()instead of smtplib.SMTP()works for me. Try this.

使用smtplib.SMTP_SSL()而不是smtplib.SMTP()对我有用。尝试这个。

回答by Onur Tuna

I have realised a strange behavior. I have used similar codes mentioned both the question and answers. My code has been working for the last days. However, today I encountered the error message mentioned in the question.

我意识到了一种奇怪的行为。我使用过类似的代码提到了问题和答案。我的代码最近几天一直在工作。但是,今天我遇到了问题中提到的错误消息。

My solution: I had tried my successful attempt via library network. Today I have tried it via Starbucks network (over captive portal). I changed it to my mobile network. It started working again.

我的解决方案:我通过图书馆网络尝试了我的成功尝试。今天我通过星巴克网络(通过强制门户)进行了尝试。我把它改成了我的移动网络。它又开始工作了。

Possibly, Google rejects requests from unreliable networks.

可能是 Google 拒绝了来自不可靠网络的请求。

回答by Sohel Pathan

I was facing the same problem. In my case, password was changed just few days back. So, it was giving the error. As I updated the password in code, its working like a charm...!!!

我面临同样的问题。就我而言,几天前更改了密码。所以,它给出了错误。当我在代码中更新密码时,它就像一个魅力......!!!

回答by Daniel Butler

Googlers: I had a test smtp server running locally. I was getting this error because I was shutting down the local smtp server before closing the client smtp.

Google 员工:我有一个在本地运行的测试 smtp 服务器。我收到此错误是因为我在关闭客户端 smtp 之前关闭了本地 smtp 服务器。