15

我正在尝试连接到 Gmail SMTP 邮件服务器并执行给我的框架代码所概述的任务。只允许使用sockets (所以不允许使用smtplib)。我需要:发送HELO命令MAIL FROM、、、RCPT TODATA

有很多类似问题的案例贴出来了,但都没有得到正确的答案。例如: 在 Python 中实现传输层安全性 - 简单邮件客户端

该程序需要smtp.gmail.com通过端口连接587。我采取了两种不同的方法:

  1. 使用 STARTTLS:

    mailserver = 'smtp.gmail.com'
    clientSocket = socket(AF_INET, SOCK_STREAM)
    clientSocket.connect((mailserver, 587))
    recv = clientSocket.recv(1024)
    print recv
    if recv[:3] != '220':
        print '220 reply not received from server.'
    
    #Send HELO command and print server response
    heloCommand = 'HELO Alice\r\n'
    clientSocket.send(heloCommand)
    recv1 = clientSocket.recv(1024)
    print recv1
    if recv1[:3] != '250':
        print '250 reply not received from server.'
    
    #Send MAIL FROM command and print server response.
    command = "STARTTLS\r\n"
    clientSocket.send(command)
    recvdiscard = clientSocket.recv(1024)
    print recvdiscard
    clientSocket.send("MAIL From: email\r\n")
    recv2 = clientSocket.recv(1024)
    print recv2
    if recv2[:3] != '250':
        print '250 reply not received from server.'
    
  2. 使用 SSL:

    clientSocketSSL = ssl.wrap_socket(clientSocket)
    

    然后clientSocketSSL替换clientSocket. STARTTLS 行也被删除并import ssl添加到顶部。

使用第一种方法时,该MAIL FROM:命令不返回任何内容。我得到以下输出:

250 mx.google.com at your service

220 2.0.0 Ready to start TLS

250 reply not received from server.

使用 SSL 时,我得到的结果与链接的帖子相同:

ssl.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

我在这里错过了什么吗?我想我最好的选择是使用 TLS,但我不知道该怎么做……我的MAIL FROM命令有问题吗?

4

2 回答 2

10

使用 SSL 时,需要连接到 465 端口,而不是 587 端口。如果使用 STARTTLS,仍然需要使用ssl.wrap_socket,您稍后再做 - 具体来说,在收到对命令的220响应之后。STARTTLS做完之后STARTTLS,你应该再做HELO一次,因为服务器应该忘记之前发生的任何事情STARTTLS

无论哪种情况,smtp.google.com 端口 465 和 587 上的服务器仍然不会返回对该命令的250响应MAIL,因为它们要求您在发送邮件之前进行身份验证。相反,您会收到530回复。您需要使用AUTH带有 gmail.com 凭据的命令进行身份验证,然后才能MAIL在这些服务器上成功使用。

如果您不想进行身份验证,并且根据您需要做什么的详细信息,您可以尝试使用在 gmail.com 的 MX 记录中找到的服务器的端口 25。目前,服务器是 gmail-smtp-in.l.google.com 并支持 STARTTLS。

于 2012-10-21T22:54:04.990 回答
1

之后STARTTLS,调用

clientSocket = ssl.wrap_socket(clientSocket)
于 2019-03-21T06:38:45.613 回答