在前面的本系列文章中我们已经学会了邮件的发送和收取。但在收取中我们看到的是一串串的乱码,回忆前面的发送过程,我们会奇怪:我们前面的邮件是明文啊。为什么明文的邮件明明也可以正常工作,还要弄乱码似的字符串编码呢?让我们先来看一下前面发送过的邮件内容:

From: "test1@newbt.net" <test1@newbt.net>
To: "clq@newbt.net" <clq@newbt.net>
Subject: test
Date: Sun, Jan :: GMT Hello World.

从中我们可以看到,其实可以直接在"记事本"中把邮件直接写出来。这是因为电子邮件的格式是 mime 而最简单的 mime 格式并不复杂。mime 当然也是有 rfc 文档进行说明的,不过明显太过复杂,我们先不要管它,先直接直观的看看眼前的这个邮件的格式。前面几行比较简单,我们猜也能猜出来,无非是说明了邮件的发件人、收件人这样的信息。后面的内容也简单啊,不就是邮件内容嘛!但是这里就有一个 mime 初学者非常容易出错的地方,后面的内容不仅仅是电子邮件的内容那么简单。实际上它包含了分隔符。什么分隔符号?你会问。我要说这封邮件里包含了两部分:一部分是头信息,包括发件人、收件人、标题、日期;另一部分是内容 "Hello World." 你能从上面的内容中找到它们的分隔符号是什么吗?大部分的同学仔细看过都会说,我看得出来是两部分,但是分隔符号是什么我真不知道。这个就是直观感受和程序处理的区别了,一眼看过去我们似乎能知道是两部分,但具体的就要知道格式的标准了。在这里,它的标准说明是:分隔符号是一个空行,不过在程序中它应该或者说必须描述为 "字符串流中的第一个空行前是头信息" 我不能说之后的就是内容,虽然这封信里看起来是这样。只能说对于这封信来说后面的内容是具体的信息,可以用下图表示:

在继续往下说以前我们要明白 mime 实际上在 http 中和 email 中是不太一样的,学过 http 的 mime 内容的同学要注意了:mime 在电子邮件中要比 http 中复杂得多,虽然它们是同一个标准

这里要再提出一个问题,如果我们要写一个中文的标题应该怎么写?你会说,改 subject 那里为"中文标题"就可以啦。如果我们这样做的话,确实对方可以收到一封中文的邮件。但我要说的是这样做是错误的。

(错误的中文标题做法)

我们前面的文章已经说过了,中文的内容在传统上是要使用编码的,所以正确的标题应该是下面的这样:

这里使用的编码方式就是前面说过的 base64。不过在邮件编码中还有一种更传统的,那就是"quoted-printable"编码,例如以下的这封 facebook 的信件内容就是这种编码的。

所以我们就明白了,要处理好电子邮件的 mime 那么就要先处理好这些编码格式,幸好常用的编码就这两种,而 base64 我们前面又掌握了。所以我们只要再学会"quoted-printable"编码就可以了。

其实"quoted-printable"说来也很简单,基本上就是我们常用的 http 的网址的编码,即将一个不可打印字符按16进制转换成基本字符串,然后在前面加上"="号就可以了,所以一个普通字符转换后要变成三个字符,是比较占空间的。不过现在是地球村时代,我们要特别注意字符集的处理,具体处理我们下一篇用纯C的代码来做一个示例。好了这一次的内容就到这里了。

注:查看电子邮件源码的话,直接在163 这样的站点上是看不到的,可以搜索一下 foxmail4.2 (最新版本我没试过);也可以用笔者的 eemail ,不过早期版本 mime 标题部分不完善,请到以下地址下载最新版本:

http://newbt.net/ms/vdisk/show_bbs.php?id={B7106D5A-A5CB-3CFE-DFEB-4A4909A9B13A}&pid=43

这篇的内容稍少,不过不先搞清楚"quoted-printable"编码是不行的,所以还是得有这一章节。

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

版权声明:

本系列文章已授权百家号 "clq的程序员学前班" . 文章编排上略有差异.

一步一步从原理跟我学邮件收取及发送 13.mime格式与常见字符编码的更多相关文章

  1. 一步一步从原理跟我学邮件收取及发送 2.邮箱的登录和绕不开的base64

    一步一步从原理跟我学邮件收取及发送 2.邮箱的登录和绕不开的base64 好了,经过本系列上一篇文章 "1.网络命令的发送",假设大家已经掌握了 email 电子邮件的命令发送的方 ...

  2. 一步一步从原理跟我学邮件收取及发送 3.telnet命令行发一封信

    首先要感谢博客园管理员的及时回复,本系列的第二篇文章得以恢复到首页,这是对作者的莫大鼓励.说实在的本来我真的挺受打击的.好在管理员说只是排版上有些问题,要用代码块修饰下相关的信息.说来惭愧因为常年编码 ...

  3. 一步一步从原理跟我学邮件收取及发送 5.C语言的socket示例

    说到 C 语言版本的程序,首先要解决的问题就是兼容性. 作为 20 年开发有 10 多年是在服务端的程序员,我深刻地感受到服务端平台的两极分化之严重,linux 派对 windows 那是超级的不屑一 ...

  4. 一步一步从原理跟我学邮件收取及发送 4.不同平台下的socket

    既然是面向程序员的文章那当然不能只说说原理,一定要有实际动手的操作.    其实作为我个人的经历来说,对于网络编程,这是最重要的一章! 作为一位混迹业内近20年的快退休的程序员,我学习过很多的开发语言 ...

  5. 一步一步从原理跟我学邮件收取及发送 8.EHLO 命令详解

    我们在上一篇中解决了接收一行命令的问题后,就可以来具体的分析邮件发送过程中涉及到的 SMTP 协议内容了. 首先来看通讯过程中的第一个内容:服务器在客户端连接上来后会主动发送一个问好的信息,所以这第一 ...

  6. 一步一步从原理跟我学邮件收取及发送 10.四句代码说清base64

    经过前几篇的文章,大家应该都能预感到一定要讲解 base64 函数的内容了.是的,马上要到程序登录的代码,base64 是必须要实现的. base64 很早以前我就接触了,在项目中也很喜欢用.但每换一 ...

  7. 一步一步从原理跟我学邮件收取及发送 11.完整的发送示例与go语言

    经过了这个系列的前几篇文章的学习,现在要写出一个完整的 smtp 邮件发送过程简直易如反掌.    例如我们可以轻松地写出以下的纯 C 语言代码(引用的其他C语言文件请看文末的 github 地址): ...

  8. 一步一步从原理跟我学邮件收取及发送 9.多行结果与socket的阻塞

    前几篇的文章发表后,有网友留言说没有涉及到阻塞的问题吗?在 socket 的编程当中,这确实是个很重要的问题.结合目前我们文章的内容进度,我们来看看为什么说阻塞概念很重要. 接着上篇的内容,当我们发送 ...

  9. 一步一步从原理跟我学邮件收取及发送 12.telnet命令行收一封信pop3

    本系列上一篇文章中我们就说到了,这一次我们要说 pop3 收信了.虽然我觉得应该先说完 mime 格式,不过估计大家已经不耐烦了 -- 怎么老在说发送啊?我们要看收取!    好吧,来啦,来啦!收取邮 ...

随机推荐

  1. 搭建mybatis时的小问题

    1.源文件中的xml文件经过编译后没有打包到classes中去,在源文件包中写的mapper文件运行时找不到. 解决办法: pom文件build下添加编译时加入xml和resource文件下的所有文件 ...

  2. 版本控制——TortoiseSVN (4)多版本并行开发 B

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  3. asp.net -mvc框架复习(7)-基于MVC搭建用户登录项目框架

    整体框架: 一.搭建Model层 1.添加通用数据访问类 2.添加实体类(封装和传递数据,和数据库中数据表对应) 3.添加数据访问类(通常和实体类同名,但是后缀名发生改变) 二.搭建控制器层Contr ...

  4. asp.net -mvc框架复习(1)-ASP.NET网站开发概述

    1.网站开发的基本步骤: 2.网站开发的需要的知识结构 (1)网站开发前台页面技术 页面设计:HTML  .CSS+DIV 页面特效:JavaScript.jQery (2)OOP编程核心公共技能 C ...

  5. 无法打开物理文件 操作系统错误 5:拒绝访问 SQL Sever

    今天分离附加数据库,分离出去然后再附加,没有问题.但是一把.mdf文件拷到其它文件夹下就出错,错误如下:    无法打开物理文件 "E:\db\homework.mdf".操作系统 ...

  6. redis 安装实战(10步完成安装)

    1 下载zip :https://redis.io/download   ---->redis-4.0.6 2 上传:利用wcp 上传到/usr/local/soft/ 3 解压:tar -zv ...

  7. 存储管理工具StorageExplorer的基本使用

    本文主要介绍Azure StorageExplorer工具的安装及基本使用 1.打开Azure官方链接:https://www.azure.cn/downloads/ 2.按照向导进行安装 3.可以通 ...

  8. 实现iota函数

    void Reverse(char *s) { char temp; char *p = s; char *q = s; while (*p != '\0') { p ++; } q --; whil ...

  9. 流API--使用并行流

    这篇博客一起来研究下使用并行流.借组多核处理器并行执行代码可以显著提高性能,但是并行编程可能十分复杂且容易出错,流API提供的好处之一是能够轻松可靠的并行执行一些操作.请求并行处理流,首先要获得一个并 ...

  10. Tomcat常用操作

    Tomcat简介 TOMCAT是APACHE JAKARTA软件组织的一个子项目,TOMCAT是一个JSP/SERVLET容器,它是在SUN公司的JSWDK(JAVA SERVER WEB DEVEL ...