邮件协议解析 and gmime 库的应用 流程

本文详细介绍了邮件系统中常用的POP3、SMTP、IMAP协议的区别,并解析了邮件内容及标题的编码方式,包括Base64、Quoted-Printable等传输编码如何影响中文显示,最后推荐使用UTF-8作为统一编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、  涉及 到得 邮件有三种,pop ,smtp, imap,

 首先看一下 三者的区别

    pop3 和 imap 都是接受 邮件的 协议, 不过 pop3 与服务器之间的关联不是同步,本地pop3 对邮件处理 不会影响服务器上的邮件, 而imap 与之相反,客户端的操作都会反馈到服务器上,对邮件进行的操作,服务器上的邮件也会做相应的动作。两者都可以让用户离线阅读,imap一个突出显著的功能:IMAP提供的摘要浏览功能可以让你在阅读完所有的邮件到达时间、主题、发件人、大小等信息后才作出是否下载的决定。此外,IMAP 更好地支持了从多个不同设备中随时访问新邮件。

    

   总之,IMAP 整体上为用户带来更为便捷和可靠的体验。POP3 更易丢失邮件或多次下载相同的邮件,但 IMAP 通过邮件客户端与webmail 之间的双向同步功能 很好地避免了这些问题。

   SMTP 的全称是“Simple Mail Transfer Protocol”,即简单邮件传输协议。它是一组用于从源地址到目的地址传输邮件的规范,通过它来控制邮件的中转方式。SMTP 协议属于 TCP/IP 协议簇,它帮助每台计算机在发送或中转信件时找到下一个目的地。SMTP 服务器就是遵循 SMTP 协议的发送邮件服务器。
   SMTP 认证,简单地说就是要求必须在提供了账户名和密码之后才可以登录 SMTP 服务器,这就使得那些垃圾邮件的散播者无可乘之机。
增加 SMTP 认证的目的是为了使用户避免受到垃圾邮件的侵扰。

   《其中,imap和pop3 密码都是明文传输, smtp密码则采用表示、base64编码》

二、切入正题

       int  fd = open(eml_name,O_RDONLY,0);

      GMimeMessage * message = NULL;

      message = get_gmime_message(fd); //获取邮件,

      char* tmp = g_mime_message_get_sender(message); //获取发送者。

      char *tmp = g_mime_message_get_subject(message);//获取标题

 

===========================

电子邮件乱码问题

当一段 Text 或者 HTML 通过电子邮件传送时,发送的内容首先通过一种指定的字符编码转化成“字节串”,然后再把“字节串”通过一种指定的传输编码(Content-Transfer-Encoding)进行转化得到另一串“字节串”。比如,打开一封电子邮件源代码,可以看到类似的内容:

Content-Type: text/plain;
charset=”gb2312″
Content-Transfer-Encoding: base64
sbG+qcrQuqO17cf4yee74bGjz9W7+b3w zA7dbQ0MQNCg0KvPKzxqO6uqO17cnnsaPW0ND
EDQoNCg==

最常用的 Content-Transfer-Encoding 有 Base64 和 Quoted-Printable 两种。在对二进制文件或者中文文本进行转化时,Base64 得到的“字节串”比 Quoted-Printable 更短。在对英文文本进行转化时,Quoted-Printable 得到的“字节串”比 Base64 更短。

邮件的标题,用了一种更简短的格式来标注“字符编码”和“传输编码”。比如,标题内容为 “中”,则在邮件源代码中表示为:

// 正确的标题格式
S ject: =?GB2312?B?1tA=?=

其中,

第一个“=?”与“?”中间的部分指定了字符编码,在这个例子中指定的是 GB2312。

“?”与“?”中间的“B”代表 Base64。如果是“Q”则代表 Quoted-Printable。

最后“?”与“?=”之间的部分,就是经过 GB2312 转化成字节串,再经过 Base64 转化后的标题内容。

如果“传输编码”改为 Quoted-Printable,同样,如果标题内容为 “中”:

// 正确的标题格式
S ject: =?GB2312?Q?=D6=D0?=

如果阅读邮件时出现乱码,一般是因为“字符编码”或“传输编码”指定有误,或者是没有指定。比如,有的发邮件组件在发送邮件时,标题 “中”:

// 错误的标题格式
S ject: =?ISO-8859-1?Q?=D6=D0?=

这样的表示,实际上是明确指明了标题为 [0x00D6, 0x00D0],即 “??”,而不是 “中”。


五、有没有万金油?

 

在如此多种编码和字符集弄的我们眼花缭乱的情况下,我们只需选择一种兼容性最好的编码方式和字符集,让它成为我们程序子系统之间交互的编码契约,那么从此恼人的乱码问题即将远离我们而去 — 这种兼容性最好的编码就是UTF-8!
毕竟GBK/GB2312是国内的标准,当我们大量使用国外的开源软件时,UTF-8才是编码界最通用的语言。

 

我们来总结一下这几种编码格式所需要的字节个数以及各自的优缺点。

编码范围UTF-8UTF-16UTF-32GB18030 *
U+000000 – U+00007F1241
U+000080 – U+00009F
U+0000A0 – U+0003FF
U+000400 – U+0007FF
2242
U+000800 – U+003FFF
U+004000 – U+00FFFF
3242
U+010000 – U+03FFFF
U+040000 – U+10FFFF
4444

备注:GB18030并不是真正意义上的Unicode编码,仅作参考

UTF-8、UTF-16和UTF-32都可以表示有效编码空间(U+000000-U+10FFFF)内的所有Unicode字符。

使用UTF-8编码时ASCII字符只占1个字节,存储效率比较高,适用于拉丁字符较多的场合以节省空间。

对于大多数非拉丁字符(如中文和日文)来说,UTF-16所需存储空间最小,每个字符只占2个字节。

Windows NT内核是Unicode(UTF-16),采用UTF-16编码在调用系统API时无需转换,处理速度也比较快。

采用UTF-16和UTF-32会有LE和BE之分,而UTF-8则没有字节顺序问题,所以UTF-8适合传输和通信。

UTF-32采用4字节编码,一方面处理速度比较快,但另一方面也浪费了大量空间,影响传输速度,因而很少使用。


六、实例

 

下面,举一个实例。

 

打开“记事本”程序Notepad.exe,新建一个文本文件,内容就是一个“严”字,依次采用ANSI,Unicode,Unicode big endian 和 UTF-8编码方式保存。

然后,用文本编辑软件UltraEdit中的“十六进制功能”,观察该文件的内部编码方式。

1)ANSI:文件的编码就是两个字节“D1 CF”,这正是“严”的GB2312编码,这也暗示GB2312是采用大头方式存储的。

2)Unicode:编码是四个字节“FF FE 25 4E”,其中“FF FE”表明是小头方式存储,真正的编码是4E25。

3)Unicode big endian:编码是四个字节“FE FF 4E 25”,其中“FE FF”表明是大头方式存储。

4)UTF-8:编码是六个字节“EF BB BF E4 B8 A5”,前三个字节“EF BB BF”表示这是UTF-8编码,后三个“E4B8A5”就是“严”的具体编码,它的存储顺序与编码顺序是一致的。


七、参考文档

http://webcenter.hit.edu.cn/articles/2009/04-01/04193356.htm

 

http://www.r nyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

http://www.regexlab.com/zh/encoding.htm

http://tech.ddvip.com/2008-11/122794544296212.html

http://www.cnblogs.com/baoq n/archive/2007/12/04/981721.html

字符集和编码的历史:http://www.javaeye.com/topic/398782

http://hi.baidu.com/xlnan/blog/item/612c0250f968bd6b853524ad.html

http://hi.baidu.com/hailwater/blog/item/85ea38e7636de325b93820ab.html< >

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

tiny丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值