1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Python 使用STMP协议发送邮件

Python 使用STMP协议发送邮件

时间:2024-01-03 20:40:41

相关推荐

Python 使用STMP协议发送邮件

引言

问题基于《计算机网络自定向下》第二章的课后套接字编程作业:邮件客户

题目的下载链接:python 压缩包

题目如下:

这个实验结束时,您将能够更好地了解SMTP协议。您还将获得使用Python实现标准协议的经验。您的任务是开发一个简单的邮件客户端,它可以向任何收件人发送电子邮件。您的客户端将需要连接到邮件服务器,使用SMTP协议与邮件服务器进行对话,并向邮件服务器发送电子邮件消息。Python提供了一个名为smtplib的模块,该模块内置了使用SMTP协议发送邮件的方法。但是,我们不会在这个实验室中使用这个模块,因为它隐藏了SMTP和套接字编程的细节。为了限制垃圾邮件,一些邮件服务器不接受来自任意来源的TCP连接。对于下面描述的实验,您可能需要尝试同时连接到大学邮件服务器和一个流行的Webmail服务器,例如AOL邮件服务器。你也可以试着在家里和大学校园里建立联系。

附加题

您当前的SMTP邮件客户端只处理在电子邮件正文中发送的文本消息。修改您的客户端,使它可以发送包含文本和图像的电子邮件。

正文

我选择的连接的是自己QQ的邮箱服务器, IP地址为58.251.106.181。为了能够进行试验,需要先登录网页QQ邮箱,在设置-账户中找到如下地方生成一个授权码。

首先要知道SMTP的基本命令,参考SMTP命令行

建立与STMP服务器(58.251.106.181)的25号端口TCP连接:

from socket import *import base64# Choose a mail server (e.g. Google mail server) and call it mailservermailserver = '58.251.106.181'## Create socket called clientSocket and establish a TCP connection with mailserver clientSocket= socket(AF_INET, SOCK_STREAM)clientSocket.connect((mailserver ,25))recv = clientSocket.recv(1024).decode()print(recv)if recv[:3] != '220':print('220 reply not received from server.')

返回:220 XMail Esmtp QQ Mail Server.

先HELO,再使用qq邮箱和授权码(需要base64编码)进行登录,

# Send HELO command and print server response.heloCommand = 'HELO Alice\r\n'clientSocket.send(heloCommand.encode())recv1 = clientSocket.recv(1024).decode()print(recv1)if recv1[:3] != '250':print('250 reply not received from server.')# Send auth login command and print server response.heloCommand = 'auth login\r\n'clientSocket.send(heloCommand.encode())recv1 = clientSocket.recv(1024).decode()print(recv1) print(base64.b64decode(recv1[4:]).decode())#decode("base64","strict")# Send users command and print server response.users = base64.b64encode(b'youQQemail@') +"\r\n".encode()print(users)clientSocket.send(users)recv1 = clientSocket.recv(1024).decode()print(recv1)# Send password and print server response.password = base64.b64encode(b'你的授权码') +"\r\n".encode()print(password)clientSocket.send(password)recv1 = clientSocket.recv(1024).decode()print(recv1)

返回:

250--9.46.14.43-20697823

250-SIZE 73400320

250 OK

334 VXNlcm5hbWU6(Username:)

334 UGFzc3dvcmQ6(Password:)

235 Authentication successful

显示登陆成功就可以发送信件了

然后使用mail from和rcpt to 传输发送方和接收方;我这里使用的发送方是我的QQ邮箱,接受方是网易邮箱,然后发送DATA信令就可以开始传输邮件内容了

# Send MAIL FROM command and print server response.clientSocket.send("mail from:<XXXXXXXX@>\r\n".encode())recv1 = clientSocket.recv(1024).decode()print(recv1) # Send RCPT TO command and print server response. clientSocket.send("rcpt to:<XXXXXXXXX@>\r\n".encode())recv1 = clientSocket.recv(1024).decode()print(recv1) # Send DATA command and print server response. clientSocket.send("DATA\r\n".encode())print(clientSocket.recv(1024).decode())

返回:

250 OK

250 OK

354 End data with <CR><LF>.<CR><LF>.

最后一行告诉我们要用 <CR><LF>.<CR><LF>.作为邮件内容的结尾,因为服务器并不知道我们的邮件有多长,对于它来说,TCP提供一个比特流,所以需要一个邮件结尾标志

接下来就是直接发送邮件内容了,但是内容需要满足一定的格式邮件客户段才可以解析。可以参考这

headline = '''From: XXXXXXXXXX@\\r\nTo: XXXXXXXXXX@\\r\nSubject:Test for SMTP command\\r\n\r\n'''msg = "This is my test!"endmsg = "\r\n.\r\n."# Send message data.clientSocket.send(headline.encode())clientSocket.send(msg.encode())# Message ends with a single period.clientSocket.send(endmsg.encode())print(clientSocket.recv(1024).decode())# Send QUIT command and get server response.clientSocket.send("quit".encode())

然后你就可以接受到邮件了

附加题

需要同时传输文字和图片。我们需要对图像也进行base64编码进行传输,还需要配置一下MIME的信息头

参考smtp协议 文本图片数据组合

登录代码不变,修改后半部分代码:

headline = '''From: XXXXXXXXX@\\r\nTo: XXXXXXXXX@\\r\nSubject:Test for SMTP command\\r\nMIME-Version: 1.0 \\r\nContent-Type: multipart/mixed; boundary="1234DED00099A";\\r\nContent-Transfer-Encoding: 7bit \r\n\r\n'''subTextHead = '''--1234DED00099A\r\nContent-Type: text/plain; charset=us-ascii \\r\nContent-Transfer-Encoding: 7bit \r\n\r\n'''subImgHead = '''--1234DED00099A\r\nContent-Type: image/jpg; name="dog.jpg";\\r\nContent-Transfer-Encoding: base64 \\r\nContent-Description: ""A photo of dog""\\r\n\r\n'''subEnd = '\r\n--XX-1234DED00099A--\r\n'msg = "This is my test!"endmsg = "\r\n.\r\n."# Send DATA command and print server response. clientSocket.send("DATA\r\n".encode())print(clientSocket.recv(1024).decode())# Send message data.clientSocket.send(headline.encode())clientSocket.send(subImgHead.encode())with open('dog.jpg','rb') as f:img_data = f.read()base64_data = base64.b64encode(img_data)clientSocket.send(base64_data)clientSocket.send("\r\n".encode())clientSocket.send(subTextHead.encode())clientSocket.send(msg.encode())clientSocket.send("\r\n".encode())# Message ends with a single period.clientSocket.send(endmsg.encode())print(clientSocket.recv(1024).decode())# Send QUIT command and get server response.clientSocket.send("quit".encode())

结果NICE!:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。