要想各种邮件处理程序能识别我们所写的电子邮件,能从我们所书写的电子邮件中分析和提取出发件人,收件人,邮件主题和邮件内容以及附件等信息,那么我们所写的电子邮件必须要遵循一定的格式要求,正如我们上一篇博客 手工体验smtp和pop3协议 ,我们在发送邮件时有固定的写法。而这种邮件内容的基本格式和具体细节分别是由 RFC822 文档和 MIME 协议定义的。

1、RFC822 邮件格式

  英文参考文档如下:https://tools.ietf.org/html/rfc822

  RFC822 文档中定义的文件格式包括两个部分:邮件头和邮件体。在上一篇博客,我们通过SMTP服务发送一封邮件,然后用POP3服务器接收。邮件接收内容如下图红色框所显示:

  

  这上面显示的不全,我这里将其内容整理出来,并在每行左边加上标号:

1 Received: from smtpbg5.qq.com (unknown [183.60.61.230])by mx6 (Coremail) with SMTP id OMCowACXv+ssf99ZD5FqAg--.5570S3;Thu, 12 Oct 2017 22:41:48 +0800 (CST)
2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qq.com; s=s201512;t=1507819308; bh=N2xK6iU/bt0tcntOdutSQ3tkYXbTtOi08RT+HjuXmBc=;h=From:To:Subject:Mime-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID;b=lzBtxAWw0+HB1bGLkkCqlUeU4bvVoMxDp3UZTKq3YCIJt5Ypu4FkE0m5rrrpcxF0DW0/PQajrQTughLTmpjoudI5aDWjfrfkOc1Z0+ltaAraoZfdE5HmNQ0hxQstNa+IbjCGMVEzCOMikVm5qklyCz/1Lwd5mBJ90YkknS3sL08=
3 X-QQ-FEAT: Gf8h89u9tNwRjwDYIPPhYegibbvTgUmwr4I/ntV6mwr6YOyFiWpUpVj+bCsJztAz24NjMs/p1D8BXG7LYvZRCPMPQV7jdW3AKjTclrSS9xE29fxWsEjYk5QlD1cMIuhHF9Po1HMwWKIZX8q6smehIwr+t/du8sprvHVue4ty5KMPeWw967qaAZgta5hcnRtgajhZRcIumVxr+K4/nY7I+wwNenOTfHT4Ly4K1Ne+vD7VNJbLHH674HEJ2CsoSEEBW7X/LeeSq6M=
4 X-QQ-SSF: 0001000000000010000000000000007
5 X-HAS-ATTACH: no
6 X-QQ-BUSINESS-ORIGIN: 2
7 X-Originating-IP: 113.57.253.69
8 X-QQ-STYLE:
9 X-QQ-mid: webmail4t1507819307t482382910 From: "=?ISO-8859-1?B?MTEzMjgwMzk1MQ==?=" <1132803951@qq.com>
11 To: "=?ISO-8859-1?B?MTgyNzEyNjU3MzI=?=" <18271265732@163.com>
12 Subject: hello world
13 Mime-Version: 1.0
14 Content-Type: multipart/alternative;boundary="----=_NextPart_59DF7F2B_08CB07D0_339F08F2"
15 Content-Transfer-Encoding: 8Bit
16 Date: Thu, 12 Oct 2017 22:41:47 +0800
17 X-Priority: 3
18 Message-ID: <tencent_9EFED46440A5BAD43E6BC680FAC8A58E460A@qq.com>
19 X-QQ-MIME: TCMime 1.0 by Tencent
20 X-Mailer: QQMail 2.x
21 X-QQ-Mailer: QQMail 2.x
22 X-QQ-SENDSIZE: 520
23 Received: from qq.com (unknown [10.137.130.92])by smtp.qq.com (ESMTP) with SMTPid ; Thu, 12 Oct 2017 22:41:47 +0800 (CST)
24 Feedback-ID: webmail:qq.com:bgweb:bgweb4
25 X-CM-TRANSID:OMCowACXv+ssf99ZD5FqAg--.5570S3
26 Authentication-Results: mx6; spf=pass smtp.mail=1132803951@qq.com; dkim=pass header.i=@qq.com
27 X-Coremail-Antispam: 1Uf129KBjDUn29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3AaLaJ3UbIYCTnIWIevJa73UjIFyTuYvj4RWLvtDUUUU28 This is a multi-part message in MIME format.29 Content-Type: text/plain;charset="ISO-8859-1"
30 Content-Transfer-Encoding: base6431 PGRpdj48c3BhbiBzdHlsZT0iZm9udC1mYW1pbHk6ICdsdWNpZGEgR3JhbmRlJywgVmVyZGFu
YSwgJ01pY3Jvc29mdCBZYUhlaSc7IGxpbmUtaGVpZ2h0OiAyMy44cHg7Ij5UaGlzIGlzIHRo
ZSBmaXJzdCBlbWFpbCBzZW50IGJ5IGhhbmQgdXNpbmcgdGhlIFNNVFAgcHJvdG9jb2w8L3Nw
YW4+PC9kaXY+

  上面便是 RFC822 所定义的邮件格式,从第 1 行到第 30 行都是邮件头,第 31 行是邮件体(经过base64加密过了,有兴趣的大家可以解码看看)。而邮件头和邮件体之间以一个空行间隔,邮件头部分是由多个头字段和字段内容组成,分别表示收件人,发件人,发件时间,主题等信息。还有一些信息是对应的SMTP服务器在邮件传递过程中所加上的,我们知道现实生活中的邮局在处理邮件时,通常都会在信封上加上邮戳,表示这封邮件在什么时候经过了哪个邮局哪个部门处理,我们上个例子是QQ邮箱发给163邮箱的。而SMTP服务器按从下往上的方式添加信息,即先添加的字段位于后添加字段的后面。所以qq的SMTP服务器会先添加头字段,但是添加的字段会在163的SMTP服务器添加字段的下面,另外 POP3服务器也会自己添加一些字段。

  每一个邮件头以“字段名:字段值”的格式出现,即每一行邮件头的内容依次由字段名、冒号、空格、字段值、回车换行符组成。RFC822文档中定义了多个标准的邮件头字段,每一个邮件头字段表示一种特定的信息。邮件头中也可以包含自定义的头字段,这种自定义的头字段通常是某个组织或机构内部专用的。下面是对一些主要的邮件头字段的解释:

  

  我们从上可以知道,RFC822文档存在两个问题:

  ①、定义了邮件内容的主体结构和各种邮件头字段的详细细节,但是,它没有定义邮件体的格式,RFC822文档定义的邮件体部分通常都只能用于表述一段普通的文本,而无法表达出图片、声音等二进制数据。

  ②、SMTP服务器在接收邮件内容时,当接收到只有一个“.”字符的单独行时,就会认为邮件内容已经结束,如果一封邮件正文中正好有内容仅为一个“.”字符的单独行,SMTP服务器就会丢弃掉该行后面的内容,从而导致信息丢失。

  上面两个问题是致命的,当今的电子邮件,人们希望在电子邮件中嵌入图片、声音、动画和附件。但是,由于图片和声音等内容是非ASCII码的二进制数据,而RFC822邮件格式只适合用来表达纯文本的邮件内容,所以,要使用RFC822邮件格式发送这些非ASCII码的二进制数据时,必须先采用某种编码方式将它们“编码”成可打印的ASCII字符后再作为RFC822邮件格式的内容。邮件阅读程序在读取到这种经过编码处理的邮件后,再按照相应的解码方式解码出原始的二进制数据,这样就可以借助RFC822邮件格式来传递多媒体数据了。这种做法需要解决一下两个技术问题:

  一、邮件阅读程序如何知道邮件中嵌入的原始二进制数据所采用的编码方式;

  二、邮件阅读程序如何知道每个嵌入的图像或其他资源在整个邮件内容中的起止位置。

  为了解决上面两个问题,人们后来专门为此定义了MIME(Multipurpose Internet Mail Extension,多用途Internet邮件扩展)协议。

2、MIME协议

  MIME协议用于定义复杂邮件体的格式,它可以表达多段平行的文本内容和非文本的邮件内容,例如,在邮件体中内嵌的图像数据和邮件附件等。另外,MIME协议的数据格式也可以避免邮件内容在传输过程中发生信息丢失。MIME协议不是对RFC822邮件格式的升级和替代,而是基于RFC822邮件格式的扩展应用。一言以蔽之,RFC822定义了邮件内容的格式和邮件头字段的详细细节,MIME协议则是定义了如何在邮件体部分表达出的丰富多样的数据内容。

  一个采用了MIME协议的电子邮件就叫做MIME邮件,MIME邮件在RFC822文档中定义的邮件头字段的基础上,扩充了一些自己专用的邮件头字段,例如,使用MIME-Version头字段指定MIME协议的版本,使用Content-Type头字段指定邮件体的MIME类型,使用Content-Transfer-Encoding头字段指定编码方法,如下所示:    

MIME-Version:1.0Content-Type:multipart/mixed;boundary="----=_NextPart_000_0050_01C"

  其中,“multipart/mixed”部分说明邮件体中包含有多段数据,每段数据之间使用boundary属性中指定的字符文本作为分隔标识符。另外,MIME邮件也扩展了RFC822文档中已经定义了的邮件头字段的内涵,例如,定义了subject头字段中的值内容的格式,以便通过编码的方式让邮件主题中也可以使用非ASCII码的字符。subject头字段中的值嵌套在一对“=?”和“?=”标记符之间,标记符之间的内容由三部分组成:邮件主题的原始内容的字符集、当前采用的编码方式、编码后的结果,这三部分之间使用“?”进行分隔。

3、总结

  这篇博客,带上前面两篇博客,我们就将邮件的收发基本原理讲了一下。那么有人会问,实际项目中我们也需要考虑邮件的底层实现协议吗?答案是不用的,比如 sun 公司(现在已经被orcal收购了)开发的JavaMail API 就是为方便Java开发人员在应用程序中实现邮件接收和发送功能而提供的一套标准开发包,屏蔽了底层的邮件实现协议,那么下一篇博客我们就来用JavaMail 实现邮件收发功能。

邮件实现详解(三)------邮件的组织结构相关推荐

  1. 邮件服务器详解_邮件协议说明

    这是目录 什么是电子邮件? 什么是电子邮件服务器? 邮件应用协议 简述发送过程 什么是电子邮件? 电子邮件是-种用电子手段提供信息交换的通信方式,是互联网应用最广的服务. 通过网络的电子邮件系统,用户 ...

  2. 张孝祥java邮件开发_张孝祥java邮件开发详解笔记(生成文本邮件)

    package zxx.createMessage; import java.io.FileOutputStream; import java.util.Date; import java.util. ...

  3. Android init.rc文件解析过程详解(三)

    Android init.rc文件解析过程详解(三) 三.相关结构体 1.listnode listnode结构体用于建立双向链表,这种结构广泛用于kernel代码中, android源代码中定义了l ...

  4. linux 进程间通信 dbus-glib【实例】详解三 数据类型和dteeth(类型签名type域)(层级结构:服务Service --> Node(对象、object) 等 )(附代码)

    linux 进程间通信 dbus-glib[实例]详解一(附代码)(d-feet工具使用) linux 进程间通信 dbus-glib[实例]详解二(上) 消息和消息总线(附代码) linux 进程间 ...

  5. Windows 7防火墙设置详解(三)

    Windows 7防火墙设置详解(三) 一.如何禁用或启用规则 方法:只需要在需要禁用或启动的规则上,鼠标右键选择启用或禁止规则即可,或点击右侧的操作栏进行规则启用或禁止. 二.入站规则和出站规则 由 ...

  6. Android Studio 插件开发详解三:翻译插件实战

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/78113868 本文出自[赵彦军的博客] 系列目录 Android Gradle使用 ...

  7. 数据结构--图(Graph)详解(三)

    数据结构–图(Graph)详解(三) 文章目录 数据结构--图(Graph)详解(三) 一.深度优先生成树和广度优先生成树 1.铺垫 2.非连通图的生成森林 3.深度优先生成森林 4.广度优先生成森林 ...

  8. SharePoint2007安装图文详解三:安装SqlServer2005

    SharePoint2007 中的很多功能会用到数据库,如分析服务,报表服务等.本文介绍SqlServer2005的安装,数据库的安装很简单,基本上安装默认选项点击下一步即可,需要注意的地方在下面会提 ...

  9. C语言中三个数比较大小详解——三种方法

    ​ C语言中三个数比较大小详解--三种方法 方法一:if-else法 方法二:函数法 方法三:三目运算符法 C语言中比较三个数的大小有很多方法,以下是我总结的三种方法: 首先我定义 int a = 1 ...

  10. MQTT协议详解 三、MQTT控制包(CONNECT)

    文章目录 系列文章目录 前言 CONNECT(客户端请求连接服务端) 一.固定包头(2字节) 二.可变包头(10字节) 协议名字(6字节) 协议等级(1字节) 连接标识(1字节) Clean Sess ...

最新文章

  1. 数据库-数据库设计原则-范式概念
  2. php上传图片完成后的截图,php实现粘贴截图并完成上传功能
  3. 解决chrome在docky上的图标模糊或不能锁定的问题
  4. python使用try语句捕获处理异常_Python使用try except处理程序异常的三种常用方法分析...
  5. python游戏源码回合制游戏_Python回合制小游戏对战程序
  6. Centos7部署开源聊天软件rocket.chat
  7. 网易邮箱服务器怎么注册,免费网易域名邮箱申请教程
  8. 在delphi的dbgrid中插入其他可视组件_delphi教程
  9. 机器学习思维导图(基于sklearn)
  10. C语言入门教程,C语言学习教程
  11. 影子系统 是怎么一回事!-间歇博客
  12. python中的error:excepted an indented block
  13. 2020腾讯广告算法大赛赛题复现
  14. mysql表操作之完整性约束
  15. tinkpad e450c 进入 BIOS
  16. 软件体系结构与设计模式——课程总体介绍(01-03)
  17. 关于VC++运行库报错
  18. 比例导引 matlab,比例导引法Matlab仿真.docx
  19. 【MySQL】数据库机房架构与跨城容灾详解(实战篇)(MySQL专栏启动)
  20. Praat脚本-018 | Praat批量调整音量

热门文章

  1. php常用操作字符串函数,php字符串几个常用的操作函数
  2. python红色_python把红玫瑰变成蓝色女巫,将,红色,转化,为,蓝色妖姬
  3. pytorch model.eval()的作用
  4. standardscaler中参数copy的作用
  5. cocos2d实现语音_Cocos2d-x 3.2 Lua示例CocosDenshionTest(音频测试)
  6. ubuntu java 编译器_Ubuntu 16.04配置Java开发环境
  7. dj打碟怎么学_南京学DJ打碟
  8. 数组计算的数学模块----NumPy
  9. 百练OJ:2973:Skew数
  10. 2021下半年软考分数线会有变动吗?