使用Python连接SMTP(SSL或TLS)

14
我正在尝试连接到 Gmail SMTP 邮件服务器并执行给我的框架代码所述的任务。只允许使用socket(而不是smtplib)。我需要发送 HELO 命令、MAIL FROMRCPT TODATA
有很多类似的问题,但它们没有得到正确的答案。例如:Implementing Transport Layer Security in Python - Simple Mail Client 该程序需要通过端口587连接到smtp.gmail.com。我采用了两种不同的方法:
  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

  3. 使用第一种方法时,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命令有什么问题吗?


你试过这个吗?使用Python发送电子邮件 - fkl
@fayyazkl,正如我所提到的,我只能使用套接字,而不能使用smtplib。 - user1287523
首先,修复您代码中的缩进。 - Burhan Khalid
你应该使用EHLO而不是HELO。 - james.garriss
2个回答

9
当使用SSL时,需要连接到端口465而不是端口587。如果您使用STARTTLS,则仍然需要使用ssl.wrap_socket,只是稍后在收到STARTTLS命令的220响应后执行。在执行STARTTLS之后,您应该再次执行HELO,因为服务器应该忘记STARTTLS之前发生的任何事情。
在任一情况下,smtp.google.com的465和587端口的服务器仍然不会返回MAIL命令的250响应,因为它们要求您在发送邮件之前进行身份验证。相反,您将收到530响应。在这些服务器上成功使用MAIL之前,您需要使用您的gmail.com凭据使用AUTH命令进行身份验证。
如果您不想进行身份验证,并取决于您需要执行的操作的详细信息,您可以尝试使用在gmail.com MX记录中找到的服务器的25号端口。目前,该服务器是gmail-smtp-in.l.google.com并支持STARTTLS。

0
在进行了STARTTLS之后,调用

clientSocket = ssl.wrap_socket(clientSocket)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接