外勤365在线登录-beat365官网下载-36500365体育在线投注

电子邮件实现详解(上)

电子邮件实现详解(上)

阿巩

好久不见~

电子邮件是大家日常工作生活中最常用的交流方式之一,我们常提到的SMTP和POP3协议分别是用来做什么的呢?MUA和MTA又是具体指哪些组件呢?邮件发送和接收过程是怎样的?SMTP邮件格式是什么样子,用python/django又如何实现发送邮件呢?本文将一一解释上述问题,并与第三方提供的API对比学习代码结构。日拱一卒,我们开始吧~

首先简要回答下前两个问题,在有了大致概念后我们来看下邮件收发过程:

MUA(Mail User Agent):邮件用户代理。由于客户端的机器无法自主实现发信,需要通过代理如Foxmail、Outlook等邮件客户端软件来进行编辑和发信。

MTA(Mail Transfer Agent):邮件传输代理。MTA的角色相当于邮局,负责帮用户寄信和收信以及转发到其他MTA。它和MUA的关系是这样的:用户在使用MUA编辑好邮件后,点击发送,邮件会被MTA接收,并且发到目的用户的MTA上。

MDA(Mail Delivery Agent):邮件投递代理。邮件在传输过程中很有可能被转移到另外一个MTA,但是最终会有某个MTA接管这封邮件,并且负责投递。MTA将邮件传递给MDA,MDA好比当地的邮递员,他负责完成将邮件存放在服务器上,以及邮件过滤或将邮件直接投递到子文件夹等整理派发的工作。

MRA(Mail Receive Agent):与MUA进行交互,实现账户的离线邮件接收,不需要一直在线等待。好比某个用户雇佣的专程检查信箱及收信的小工。

总结一下大致流程如下:

1、用户使用MUA编辑邮件,并配置smtp服务器域名,然后寄信给MTA发送邮件。(比如使用网易账户发送邮件就要在配置smtp.163.com,这样邮件就发送到网易MTA)

2、MTA检查收件人服务器是不是自己,不是则传递给下一跳的MTA,直到传递到目的MTA。

3、目的MTA收到邮件后通过MDA进行存储和过滤。

4、MRA从MDA中收取邮件,存到用户的收件箱中。

5、MUA收取邮件,即将MRA中的邮件下载到本地。

我们再来看过程中用到的具体协议:

SMTP协议:Simple Mail Transfer Protocol,简单邮件传输协议。用于邮件客户端与SMTP邮件服务器之间以及两台SMTP服务器之间的通信规则。SMTP协议的通信双方采用一问一答的命令/响应形式进行对话。

POP3协议:Post Office Protocol,邮局协议。用于邮件客户端软件和POP3邮件服务器之间的通信规则。

IMAP协议:Internet Message Access Protocol,Internet消息访问协议,它是对POP3协议的一种扩展,也是定义了邮件客户端软件和IMAP邮件服务器的通信规则。

SMTP邮件服务器:替用户发送邮件和接收外面发送给本地用户的邮件。

POP3/IMAP邮件服务器:帮助用户读取SMTP邮件服务器接收进来的邮件。

IMAP与POP3区别:POP3协议提供了邮件下载功能,但使用POP3协议时,在客户端上的操作不会反馈到服务器上,比如创建文件夹、保存草稿、移动邮件、标记已读等;IMAP提供webmail 与电子邮件客户端之间的双向通信,IMAP协议支持邮件下载,并且支持客户端和邮箱同步更新。

在了解了基础通信协议之后,我们再回到服务器层面,假设用户A使用QQ邮箱给用户B的163邮箱发送邮件,在哪个环节用到了上述的哪个协议,过程是怎样的呢。

① 这一步对应MUA到MTA,使用到的是SMTP协议。

② 从SMTP服务器转发到目的服务器,使用到的也是SMTP协议。

③ 这一步SMTP服务器,即MTA检查收件人服务器是不是自己,发现是自己的账户,便将邮件存放到自己的内部存储空间。

④ 用户A将邮件发送之后,会通知用户B到指定邮箱收取邮件。用户B会通过邮件客户端软件先向163邮箱服务器请求,要求收取自己的邮件。使用到了POP3协议。

⑤ 收到请求后,会从自己的存储空间中取出B未收取的邮件。也使用到了POP3协议。

⑥ 取出用户B未收取的邮件后,将邮件发给用户B。也使用到了POP3协议。

以下代码源自网络,是使用foxmail接收邮件后得到的邮件源码,包括正文和两个附件(.JPG, .TXT):

代码语言:javascript复制Received:from m15-17.126.com (unknown [220.181.15.17])

bymx10 (Coremail) with SMTP id PMCowECZWSfPlodRSu6NCw--.779S2;

Mon,06 May 2013 19:41:03 +0800 (CST)

DKIM-Signature:v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; // 域名密钥识别邮件标准,判断垃圾邮件

s=s110527;h=Received:Date:From:To:Subject:Content-Type:

MIME-Version:Message-ID; bh=B57Zfi/+wCVQ61kM9GVkCECk1ax4OZVQDtnW // 不是base64编码

T4lS0x8=;b=XdeYidC7bR1a1l7x3yGAMiMR5ElDx2O4/db2iPrVc0dZ7Y7ANStu // 不是base64编码

6d9o4l9yVysfwk8vifb0eqyxV2wp28pIlfLEGZbDDpKaLMCaLAbVXdW+2hQl4ojd // 不是base64编码

sJ7NiAdF1j5X2N87wktFKA8ZK4lPhBYI1yFrNIT+PODg2NzF1CX2FDM=

Received: from zzzzyy91$126.com ( [202.205.103.22] ) by ajax-webmail-wmsvr17

(Coremail) ; Mon, 6 May 2013 19:41:01 +0800(CST)

X-Originating-IP: [202.205.103.22] //初始ip地址,同一电脑不同邮箱发邮件,该值相同

---------------------------------------------------------------------------------------------------------

DATA(以下内容由邮件客户端定义,为DATA命令后输入的内容)

--------------------------------------------------------------------------------------------------------

Date: Mon, 6 May2013 19:41:01 +0800 (CST)

From: [base64code]

To: [emailaddress]

Subject: [base64 code]

X-Priority: [integer] // 邮件优先级

X-Mailer: [Coremail Webmail Server Version SP_ntes V3.5 build // 代理发信客户端

20130412(21945.5326.5325) Copyright (c)2002-2013 www.mailtech.cn 126com]

X-CM-CTRLDATA: [base64 code] // X-邮件服务器自定义的信息段,未知作用

Content-Type:multipart/mixed; // 声明邮件内容格式

boundary="----=_Part_354288_309861106.1367840461937" // 声明邮件内容boundary

MIME-Version: 1.0 // 声明MIME版本

Message-ID: <> // X-邮件服务器自定义的信息段

X-CM-TRANSID: //X-邮件服务器自定义的信息段

X-CM-SenderInfo: // X-邮件服务器自定义的信息段

X-Coremail-Antispam: // X-邮件服务器自定义的信息段

---------------------------------------------------------

以下为邮件的内容

--------------------------------------------------------

------=_Part_354288_309861106.1367840461937 //邮件内容开始

Content-Type: multipart/alternative; //邮件内容格式

boundary="----=_Part_354290_1105600126.1367840461937" // 邮件正文boundary

------=_Part_354290_1105600126.1367840461937 //邮件正文boundary -- 正文开始

Content-Type: text/plain; charset=GBK // 邮件正文格式和字符集

Content-Transfer-Encoding: base64

[base64]mailcontent (plain)[base64] //邮件正文(文本格式)编码(base64)

------=_Part_354290_1105600126.1367840461937 // 邮件正文boundary --可选HTML格式

Content-Type: text/html; charset=GBK //邮件正文格式和字符集

Content-Transfer-Encoding: base64

[base64]mailcontent (html)[base64] //邮件正文(html格式)编码(base64)

------=_Part_354290_1105600126.1367840461937-- // 邮件正文boundary -- 正文结束

------=_Part_354288_309861106.1367840461937 // 邮件内容boundary -- 附件1开始

Content-Type: image/jpeg; name="20130324_224528_982.jpg" // 附件格式及文件名

Content-Transfer-Encoding: base64

Content-Disposition: attachment;filename="20130324_224528_982.jpg"

[base64](.jpg)image attachment[base64] //附件-图片内容编码(base64)

------=_Part_354288_309861106.1367840461937 // 邮件内容boundary -- 附件2开始

Content-Type: text/plain; name="window data type.txt" // 附件格式及文件名

Content-Transfer-Encoding: base64

Content-Disposition: attachment; filename="window datatype.txt"

[base64](.txt)plain attachment[base64] // 附件-文本内容编码(base64)

------=_Part_354288_309861106.1367840461937-- // 邮件内容boundary -- 附件结束在代码第6行我们看到MIME-Version这个字段,MIME协议(Multipurpose Internet Mail Extension,多用途Internet邮件扩展)用于定义复杂邮件体的格式,它支持在邮件体部分表达出的丰富多样的数据内容。而对于邮件内容的基本格式,由RFC822 文档定义。MIME协议即为对RFC822 文档的扩展。

邮件头标准字段解释如下:

参考:

https://blog.csdn.net/Fly2Leo/article/details/10468411?spm=1001.2014.3001.5501https://www.cnblogs.com/ysocean/p/7652934.html

http://help.163.com/10/0203/13/5UJONJ4I00753VB8.html?servCode=6010237

http://blog.sina.com.cn/s/blog_af19951a0102yz1j.html

由于涉及代码多篇幅过长,JavaMail API、Python smtplib以及django.core.mail实现邮件的收发等内容将放到下一节实现。

感谢所有TV,下期见。

END

相关推荐