Соединение прервалось при попытке отправить электронное письмо методом send_mail
У меня возникают проблемы при отправке электронной почты с помощью метода send_mail из модуля django.core.mail.
Содержание настроек электронной почты проекта следующее.
# --snip--
# Email Settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'mukukachilu@gmail.com'
EMAIL_HOST_PASSWORD = 'myfakepassword'
EMAIL_PORT = 587
EMAIL_USE_TLS = False
EMAIL_USE_SSL = False
# --snip--
Вот что я делаю в оболочке Django.
Python 3.9.7 (default, Sep 10 2021, 14:59:43)
[GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.core.mail import send_mail
>>> from django.congf import settings
>>> send_mail('Test Subject', 'Test message', settings.EMAIL_HOST_USER, ['c.mukuka@makeitworkds.com'], fail_silently=False)
После длительного зависания метода send_mail я получаю следующий Traceback.
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/root/djangoenv/lib/python3.9/site-packages/django/core/mail/__init__.py", line 61, in send_mail
return mail.send()
File "/root/djangoenv/lib/python3.9/site-packages/django/core/mail/message.py", line 284, in send
return self.get_connection(fail_silently).send_messages([self])
File "/root/djangoenv/lib/python3.9/site-packages/django/core/mail/backends/smtp.py", line 102, in send_messages
new_conn_created = self.open()
File "/root/djangoenv/lib/python3.9/site-packages/django/core/mail/backends/smtp.py", line 62, in open
self.connection = self.connection_class(self.host, self.port, **connection_params)
File "/usr/lib/python3.9/smtplib.py", line 255, in __init__
(code, msg) = self.connect(host, port)
File "/usr/lib/python3.9/smtplib.py", line 341, in connect
self.sock = self._get_socket(host, port, self.timeout)
File "/usr/lib/python3.9/smtplib.py", line 312, in _get_socket
return socket.create_connection((host, port), timeout,
File "/usr/lib/python3.9/socket.py", line 844, in create_connection
raise err
File "/usr/lib/python3.9/socket.py", line 832, in create_connection
sock.connect(sa)
TimeoutError: [Errno 110] Connection timed out
Я также выполнил команду telnet на smtp-сервере Gmail следующим образом
# telnet smtp.gmail.com 25
Trying 2a00:1450:400c:c0c::6d...
Но получаем такой ответ от telnet
telnet unable to connect to remote host: Connection timed out
Я также включил двухфакторную аутентификацию на своей учетной записи Gmail и вхожу в систему, используя пароль приложения. Я также пробовал использовать метод входа с помощью менее безопасных приложений, но все равно происходит то же самое.
Так где же я могу ошибаться?
Протокол SMTP использует соединение TCP-сокет для отправки электронной почты. На стороне клиента может быть только один TCP сокет для каждого порта.
В вашем случае Django свяжет TCP-сокет с EMAIL_PORT, указанным вами на стороне клиента, для отправки письма. Этот сокет по умолчанию имеет EMAIL_TIMEOUT None согласно документации, поэтому сокет будет существовать неопределенно долго. Вы сможете отправить сообщение в первый раз, но при втором запуске кода вы получите описанную выше ошибку, так как порт уже используется.
Вы должны указать EMAIL_TIMEOUT в настройках, чтобы закрыть сокеты через некоторый промежуток времени. Вам также следует освободить используемый TCP порт, прежде чем пытаться отправить письмо снова, следуя шагам из этой темы (или просто перезагрузить компьютер).