一步一步从原理跟我学邮件收取及发送 13.mime格式与常见字符编码
在前面的本系列文章中我们已经学会了邮件的发送和收取。但在收取中我们看到的是一串串的乱码,回忆前面的发送过程,我们会奇怪:我们前面的邮件是明文啊。为什么明文的邮件明明也可以正常工作,还要弄乱码似的字符串编码呢?让我们先来看一下前面发送过的邮件内容:
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格式与常见字符编码的更多相关文章
- 一步一步从原理跟我学邮件收取及发送 2.邮箱的登录和绕不开的base64
一步一步从原理跟我学邮件收取及发送 2.邮箱的登录和绕不开的base64 好了,经过本系列上一篇文章 "1.网络命令的发送",假设大家已经掌握了 email 电子邮件的命令发送的方 ...
- 一步一步从原理跟我学邮件收取及发送 3.telnet命令行发一封信
首先要感谢博客园管理员的及时回复,本系列的第二篇文章得以恢复到首页,这是对作者的莫大鼓励.说实在的本来我真的挺受打击的.好在管理员说只是排版上有些问题,要用代码块修饰下相关的信息.说来惭愧因为常年编码 ...
- 一步一步从原理跟我学邮件收取及发送 5.C语言的socket示例
说到 C 语言版本的程序,首先要解决的问题就是兼容性. 作为 20 年开发有 10 多年是在服务端的程序员,我深刻地感受到服务端平台的两极分化之严重,linux 派对 windows 那是超级的不屑一 ...
- 一步一步从原理跟我学邮件收取及发送 4.不同平台下的socket
既然是面向程序员的文章那当然不能只说说原理,一定要有实际动手的操作. 其实作为我个人的经历来说,对于网络编程,这是最重要的一章! 作为一位混迹业内近20年的快退休的程序员,我学习过很多的开发语言 ...
- 一步一步从原理跟我学邮件收取及发送 8.EHLO 命令详解
我们在上一篇中解决了接收一行命令的问题后,就可以来具体的分析邮件发送过程中涉及到的 SMTP 协议内容了. 首先来看通讯过程中的第一个内容:服务器在客户端连接上来后会主动发送一个问好的信息,所以这第一 ...
- 一步一步从原理跟我学邮件收取及发送 10.四句代码说清base64
经过前几篇的文章,大家应该都能预感到一定要讲解 base64 函数的内容了.是的,马上要到程序登录的代码,base64 是必须要实现的. base64 很早以前我就接触了,在项目中也很喜欢用.但每换一 ...
- 一步一步从原理跟我学邮件收取及发送 11.完整的发送示例与go语言
经过了这个系列的前几篇文章的学习,现在要写出一个完整的 smtp 邮件发送过程简直易如反掌. 例如我们可以轻松地写出以下的纯 C 语言代码(引用的其他C语言文件请看文末的 github 地址): ...
- 一步一步从原理跟我学邮件收取及发送 9.多行结果与socket的阻塞
前几篇的文章发表后,有网友留言说没有涉及到阻塞的问题吗?在 socket 的编程当中,这确实是个很重要的问题.结合目前我们文章的内容进度,我们来看看为什么说阻塞概念很重要. 接着上篇的内容,当我们发送 ...
- 一步一步从原理跟我学邮件收取及发送 12.telnet命令行收一封信pop3
本系列上一篇文章中我们就说到了,这一次我们要说 pop3 收信了.虽然我觉得应该先说完 mime 格式,不过估计大家已经不耐烦了 -- 怎么老在说发送啊?我们要看收取! 好吧,来啦,来啦!收取邮 ...
随机推荐
- 数据库复习总结(20)-存储过程以及.net调用存储过程
一.存储过程(注意区分将一段select语句进行封装叫做视图)(1)将一段t-sql脚本进行封装,以完成一个逻辑操作(2)创建存储过程: create proc 名称 ...
- -pie can only be used when targeting iOS 4.2 or later错误解决
在工程的build setting里,把IPHONEOS_DEPLOYMENT_TARGET改成4.2或以上就行了
- java实现定时任务
Java中实现定时任务执行某一业务.具体操作如下: 1.定义初始化任务 2.任务业务操作 3.定义初始化方法 4.在web.xml中注册启动 5.定义具体执行时间
- Mac下用SSH连接远程Linux或Mac服务器
1.打开Mac终端 2.切换到root登录 输入命令:sudo -i,然后输入本机密码 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px &qu ...
- socket 编程--sockaddr与sockaddr_in区别与联系(转)
在linux环境下,结构体struct sockaddr在/usr/include/linux/socket.h中定义,具体如下:typedef unsigned short sa_family_t; ...
- Assembly oth
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- html5移动端meta自动适应标签
控制显示区域各种属性: <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-sc ...
- Java进阶篇(六)——Swing程序设计(上)
Swing是GUI(图形用户界面)开发工具包,内容有很多,这里会分块编写,但在进阶篇中只编写Swing中的基本要素,包括容器.组件和布局等,更深入的内容会在高级篇中出现.想深入学习的朋友们可查阅有关资 ...
- MySQL的char和varchar针对空格的处理
MySQL的char和varchar存储和查询中包含空格的实验 MySQL版本 一.测试char包含空格的存储和查询 测试发现,存储的数据,char数据类型的右侧空格存储的时候被删除了,但是左侧空格还 ...
- java.lang.ClassNotFoundException: com.radiadesign.catalina.session.RedisSessionHandlerValve
org.apache.tomcat.util.digester.Digester.startElement Begin event threw exception java.lang.ClassNot ...