SMTP实验

一、实验目的

  1. 学习如何创建一个向任何接收方发送电子邮件的简单邮件客户。
  2. 学习了解STMP协议。

二、实验内容

  1. 开发一个简单的邮件客户端,将邮件发送给任意收件人。

  2. 客户端将需要连接到邮件服务器,使用SMTP协议与邮件服务器进行对话, 并向邮件服务器发送电子邮件。

三、实验原理

C 库中包含了用语网络通信的 socket 套接字。Socket 套接字分为流式套接口、 数据报套接口及原始套接口 3 类。

STMP协议工作原理。

Python提供了一个名为smtplib的模块,它内置了使用SMTP协议发送邮件的方法。但是我们不会在本实验中使用此模块,因为它隐藏了SMTP和套接字编程的细节。

四、实验步骤

根据提供的代码框架,完善代码,运行客户端,向自己的邮箱发送一封邮件(此处选择QQ邮箱)。

五、实验结果及分析

SMTP邮件客户端程序的大致流程如下:

  1. 与QQ邮件服务器建立TCP连接,域名"smtp.qq.com",SMTP默认端口号25。建立连接后服务器将返回状态码220,代表服务就绪(类似HTTP,SMTP也使用状态码通知客户端状态信息)。

  2. 发送"HELO"命令,开始与服务器的交互,服务器将返回状态码250(请求动作正确完成)。

  3. 发送"AUTH LOGIN"命令,开始验证身份,服务器将返回状态码334(服务器等待用户输入验证信息)。

  4. 发送经过base64编码的用户名,服务器将返回状态码334(服务器等待用户输入验证信息)。

  5. 发送经过base64编码的密码,服务器将返回状态码235(用户验证成功)。

  6. 发送"MAIL FROM"命令,并包含发件人邮箱地址,服务器将返回状态码250(请求动作正确完成)。

  7. 发送"RCPT TO"命令,并包含收件人邮箱地址,服务器将返回状态码250(请求动作正确完成)。

  8. 发送"DATA"命令,表示即将发送邮件内容,服务器将返回状态码354(开始邮件输入,以"."结束)。

  9. 发送邮件内容,服务器将返回状态码250(请求动作正确完成)。

  10. 发送"QUIT"命令,断开与邮件服务器的连接。

STMP客户端代码(password已删除)

from socket import *
import base64
msg = "\r\n I love computer networks!"
endmsg = "\r\n.\r\n"
# Choose a mail server (e.g. Google mail server) and call it mailserver
mailserver = "smtp.qq.com"
# Create socket called clientSocket and establish a TCP connection with mailserver
#Fill in start
mailPort = 25
username = "1030930044@qq.com"
password = "【已删除】"
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((mailserver,mailPort))
#Fill in end
recv = clientSocket.recv(1024).decode()
print(recv)
if recv[:3] != '220':
    print('220 reply not received from server.')
# Send HELO command and print server response.
heloCommand = 'HELO XXX\r\n'
clientSocket.send(heloCommand.encode())
recv1 = clientSocket.recv(1024).decode()
print(recv1)
if recv1[:3] != '250':
    print('250 reply not received from server.')

loginCommand = "auth login\r\n"
clientSocket.send(loginCommand.encode())
recv0 = clientSocket.recv(1024).decode()
print(recv0)
if recv0[:3] != '334':
    print('334 reply not received from server.')
clientSocket.send(base64.b64encode(username.encode('utf-8')))
clientSocket.send("\r\n".encode())
#print(clientSocket.recv(1024).decode())
clientSocket.send(base64.b64encode(password.encode('utf-8')))
clientSocket.send("\r\n".encode())
#print(clientSocket.recv(1024).decode())
# Send MAIL FROM command and print server response.
# Fill in start
fromCommand = "MAIL FROM: <1030930044@qq.com>\r\n"
clientSocket.send(fromCommand.encode())
recv2 = clientSocket.recv(1024).decode()
print(recv2)
if recv2[:3] != '250':
    print('250 reply not received from server.')
# Fill in end
# Send RCPT TO command and print server response. 
# Fill in start
rcptCommand = "RCPT TO: <1030930044@qq.com>\r\n"
clientSocket.send(rcptCommand.encode())
recv3 = clientSocket.recv(1024).decode()
print(recv3)
if recv3[:3] != '250':
    print('250 reply not received from server.')
# Fill in end
# Send DATA command and print server response. 
# Fill in start
dataCommand = "DATA\r\n"
clientSocket.send(dataCommand.encode())
recv4 = clientSocket.recv(1024).decode()
print(recv4)
if recv4[:3] != '354':
    print('354 reply not received from server.')
# Fill in end
# Send message data.
# Fill in start
clientSocket.send(msg.encode())
# Fill in end
# Message ends with a single period.
# Fill in start
clientSocket.send(endmsg.encode())
# Fill in end
# Send QUIT command and get server response.
# Fill in start
quitCommand = "QUIT\r\n"
clientSocket.send(quitCommand.encode())
recv5 = clientSocket.recv(1024).decode()
print(recv5)
if recv4[:3] != '221':
    print('221 reply not received from server.')
# Fill in end

测试结果

成功接收到邮件

gaozhenyu.chn@qq.com就是1030930044@qq.com

六、实验中遇到的问题及解决方法

编写程序运行后,无法正常登录,经网上查询资料得知QQ邮箱未开启SMTP服务,需要特定的验证码才能登录,而不是直接使用密码。

调试时又发现请求和响应不能正常进行下去,经仔细检查,猜想用户名和验证码需要进行base64加密,找到一个在线base64加密解密工具进行实验,验证了猜测,在代码中调用了Python的base64.b64encode()和encode(‘utf-8’),解决了该问题。

七、实验心得体会

学习了如何创建一个向任何接收方发送电子邮件的简单邮件客户。

更深入地理解了SMTP的工作过程,也对电子邮件的工作原理有了基本的认识。

过程中遇到了一些教材上没有提及的问题,通过从其他渠道获取资料,成功解决。让我切实体会到了,只是阅读教材,收获是很有限的,实践中会遇到很多未曾考虑到的问题,而这些问题需要自己查询资料、理解、学习、解决。

posted @ 2020-12-28 10:38  凡宇尘天  阅读(844)  评论(0)    收藏  举报