目录
简介
基于客户端软件
电子邮件系统框架
电子邮件组成
信封
内容
邮件发送/接收步骤
SMTP与MIME
简介
流程
连接建立
邮件发送
连接释放
SMTP的缺点
MIME
POP3与IMAP
简介
基于万维网
电子邮件系统框架
Python发送邮件
全部代码
结果截图
参考
电话通信需要主叫方与被叫方同时在场,有时会打扰到人们的工作或休息,因此,有了电子邮件(e-mail)。电子邮件把邮件发送到收件人使用的邮件服务器,并放在其中的收件人邮箱(mailbox)中,收件人可在自己方便时上网到自己使用的邮件服务器进行读取。这相当于互联网为用户设立了存放邮件的信箱,因此e-mail有时也称为“电子信箱”。
用户代理UA(User Agent)就是用户与电子邮件系统的接口,在大多数情况下它就是运行在用户电脑中的一个程序。因此用户代理又称为电子邮件客户端软件。用户代理向用户提供一个很友好的接口(目前主要是窗口界面)来发送和接收邮件。例如,微软公司的Outlook Express和我国张小龙制作的Foxmail。
用户代理至少应当具有以下4个功能。
(1)撰写。给用户提供编辑信件的环境。例如,应让用户能创建便于使用的通讯录(有常用的人名和地址)。回信时不仅能很方便地从来信中提取出对方地址,并自动地将此地址写入到邮件中合适的位置,而且还能方便地对来信提出的问题进行答复(系统自动将来信复制一份在用户撰写回信的窗口中,因而用户不需要再输入来信中的问题)。
(2)显示。能方便地在计算机屏幕上显示出来信(包括来信附上的声音和图像)。
(3)处理。处理包括发送邮件和接收邮件。收件人应能根据情况按不同方式对来信进行处理。例如,阅读后删除、存盘、打印、转发等,以及自建目录对来信进行分类保存。有时还可在读取信件之前先查看一下邮件的发件人和长度等,对于不愿收的信件可直接在邮箱中删除。
(4)通信。发信人在撰写完邮件后,要利用邮件发送协议发送到用户所使用的邮件服务器。收件人在接收邮件时,要使用邮件读取协议从本地邮件服务器接收邮件。
邮件服务器:互联网上有许多邮件服务器可供用户选用。邮件服务器24小时不间断地工作,并且具有很大容量的邮件信箱。邮件服务器的功能是发送和接收邮件,同时还要向发件人报告邮件传送的结果(已交付、被拒绝、丢失等)。邮件服务器按照客户服务器方式工作。邮件服务器需要使用两种不同的协议。一种协议用于用户代理向邮件服务器发送邮件或在邮件服务器之间发送邮件,如SMTP协议,而另一种协议用于用户代理从邮件服务器读取邮件,如邮局协议POP3。
这里应当注意,邮件服务器必须能够同时充当客户和服务器。
电子邮件由信封(envelope)和内容(content)两部分组成。
电子邮件地址(e-mail address),格式 username@domainname。
分为首部(header)和主体(body),在RFC 5322中规定了header(From、To、Subject、Date),一般我们填写收件人和主题即可,用户代理会帮助我们填写发件人和日期。主题部分由用户自定义,包括正文、附件等。
SMTP(Simple Mail Transfer Protocol,简单邮件传送协议),采用客户/服务器方式,熟知端口号25,由于互联网的SMTP只能传送可打印的7位ASCII码邮件,因此在1993年又提出了MIME(Multipurpose Internet Mail Extensions,通用互联网邮件扩充)。MIME在其邮件首部中说明了邮件的数据类型(如文本、声音、图像、视像等),在MIME邮件中可同时传送多种类型的数据。
SMTP规定了14条命令和21种应答信息。每条命令用几个字母组成,而每一种应答信息一般只有一行信息,由一个3位数字的代码开始,后面附上(也可不附上)很简单的文字说明。下面通过发送方和接收方的邮件服务器之间的SMTP通信的三个阶段介绍几个最主要的命令和响应消息。
只有5个SMTP命令用于发送邮件:HELO,MAIL,RCPT,DATA和QUIT。
发件人的邮件送到发送方邮件服务器的邮件缓存后,SMTP客户就每隔一定时间对邮件缓存扫描一次。如发现有邮件,就使用SMTP的熟知端口号码25与接收方邮件服务器的SMTP服务器建立TCP连接。在连接建立后,接收方SMTP服务器要发出“220 Service ready”(服务就绪)。然后SMTP客户向SMTP服务器发送HELO命令,附上发送方的主机名。SMTP服务器若有能力接收邮件,则回答:“250 OK”,表示已准备好接收。若SMTP服务器不可用,则回答“421 Service not available”(服务不可用)。
邮件的传送从MAIL命令开始。MAIL命令后面有发件人的地址。若SMTP服务器已准备好接收邮件,则回答“250OK”。否则,返回一个代码,指出原因。如:451(处理时出错),452(存储空间不够)等。
下面跟着一个或多个RCPT(recipient,收件人)命令,取决于把同一个邮件发送给一个或多个收件人。每发送一个RCPT命令,都应当有相应的信息从SMTP服务器返回,如:“250OK”,表示指明的邮箱在接收方的系统中,或“550No such user here”(无此用户),即不存在此邮箱。RCPT命令的作用就是:先弄清接收方系统是否已做好接收邮件的准备,然后才发送邮件。这样做是为了避免浪费通信资源,不至于发送了很长的邮件以后才知道地址错误。
再下面就是DATA命令,表示要开始传送邮件的内容了。SMTP服务器返回的信息是:“354 Start mail input;end with
邮件发送完毕后,SMTP客户应发送QUIT命令。SMTP服务器返回的信息是“221(服务关闭)”,表示SMTP同意释放TCP连接。邮件传送的全部过程即结束。
由于SMTP存在一些缺点,MIME对传送的内容进行了一些扩充,进行了ASCII码和非ASCII码之间的转换。
MIME主要包括以下三部分内容:
为适应于任意数据类型和表示,每个MIME报文包含告知收件人数据类型和使用编码的信息。MIME把增加的信息加入到原来的邮件首部中。
下面是MIME增加的5个新的邮件首部的名称及其意义(有的可以是选项)。
类型 | 子类型举例 |
---|---|
text(文本) | plain,html,xml,css |
image(图像) | gif,jpeg,tif |
audio(音频) | basic,mpeg,mp3 |
video(视频) | mpeg,mp4,quicktime |
model(模型) | vrml |
application(应用) | octet-stream,pdf,javascript,zip |
message(报文) | http,rfc822 |
multipart(多部分) | mixed,alternative,parallel,digest |
目前常用的邮件读取协议有两种,一种是POP3,即POP(PostOffice Protocol,邮局协议)的版本3,熟知端口110。之前是下载并删除的方式,之后经过扩展,可以下载并保留一段时间。
另一种是IMAP(Internet Message Access Protocol,网际报文存取协议),当用户计算机上的IMAP客户程序打开IMAP服务器的邮箱时,用户就可看到邮件的首部。若用户需要打开某个邮件,则该邮件才传到用户的计算机上。用户可以根据需要为自己的邮箱创建便于分类管理的层次式的邮箱文件夹,并且能够将存放的邮件从某一个文件夹中移动到另一个文件夹中。用户也可按某种条件对邮件进行查找。在用户未发出删除邮件的命令之前,IMAP服务器邮箱中的邮件一直保存着。。
为了更加方便,人们不再愿意安装客户端,而是更多的使用网站,比如谷歌GMail、新浪邮箱、网易163邮箱等。
用户代理、邮件服务器等重复内容不再赘述。需要注意的是使用网站(用户代理)时我们推送邮件到服务器是使用HTTP(S)协议,拉取时也是。
"""
--coding:utf-8--
@File: send_email.py
@Author:frank yu
@DateTime: 2020.12.15 14:36
@Contact: [email protected]
@Description:
"""
import os
import smtplib
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
send_user = '你需要替换' # 发件人
password = '你需要申请' # 授权码/密码
server_address = '你需要替换' # 服务器地址
def send_email(recv, subject, text='', file=None):
# 构造一个邮件体:正文 附件
msg = MIMEMultipart()
msg['Subject'] = subject # 主题
msg['From'] = send_user # 发件人
msg['To'] = recv # 收件人
# 构建正文
part_text = MIMEText(text)
msg.attach(part_text) # 把正文加到邮件体里面去
if file is not None:
# 构建邮件附件
part_attach1 = MIMEApplication(open(file, 'rb').read()) # 打开附件
part_attach1.add_header('Content-Disposition', 'attachment', filename=os.path.basename(file)) # 为附件命名
msg.attach(part_attach1) # 添加附件
try:
# 发送邮件 SMTP
smtp = smtplib.SMTP(server_address, 25)
smtp.login(send_user, password)
smtp.sendmail(send_user, recv, msg.as_string())
print('发送成功!')
except Exception as e:
print('网络存在问题,发送失败:', e)
if __name__ == '__main__':
# send_email('你需要替换', '文本邮件发送测试', '今天天气真不错')
send_email('你需要替换', '附件邮件发送测试', '请查看附件', '你需要替换,例如:E:\北邮信息\成绩单.docx')
其中,授权码一般通过设置->更多设置来找到选项申请,新浪的如下:
发件人就是你申请授权码的这个邮箱,服务器就是SMTP服务器(发送的话)。博主是用新浪给自己的北邮邮箱发的邮件,你也可以用新浪发给新浪。
之前写了个脚本,用opencv录取视频,保存到本地,使用邮件发送后删除,打包成了exe给了朋友,偷录了一些视频(当然,事后告诉了朋友并删除了视频),发了博客后(含代码及视频截图)过段时间给封了,大家可以换个别的想法玩一玩。
《计算机网络(第7版)谢希仁》6.5
《TCP/IP详解I》第28章
RFC 5321 SMTP
RFC 2045 、2046 MIME
RFC 5322 邮件格式
RFC 1939 POP3
RFC 2449 POP3扩展
RFC 3501 IMAP4