SMTP邮件格式、SMTP 协议,SMTP的MIME写法,SMTP发送HTML邮件

转载:http://blog.sina.com.cn/s/blog_759444350100vx8u.html

MIME邮件格式

在RFC 2822文档中定义了简单的ASCII编码的Email的邮件格式,然而随着Internet的发展,Email邮件仅仅传输简单的文本已经满足不了用户的需求,为了在Email中传输大量HTML、图像、声音以及各种附件格式,一种新的扩展的邮件格式应运而生——MIME。由于在MIME邮件格式非常复杂,大量的RFC文档中对MIME邮件格式进行了定义与说明,比如RFC2045, RFC2046, RFC2047, RFC2049, RFC2231,RFC2387, RFC4288,RFC4289等。因此,MIME邮件格式为我们提供了极大的灵活性的同时也给我们解读MIME格式的Email邮件带来了极大的困难。以下就一封具体的邮件原始信息对MIME邮件格式作出一个概要的介绍。

解释几个常用且不易理解的Content-Type开头的MIME首部:

Received: from JSJ104(unknown [202.204.96.147])
    by smtp14(Coremail) with SMTP id wKjRDyJAHALkc2lFEtAjAg==.38990S2;
    Sun, 26 Nov2006 19:00:55 +0800 (CST)
Message-ID:<000601c7114a$2fd50450$9360ccca@JSJ104>
From: <ctp_41023@163.com>
To: <ctp_41023@163.com>
Subject:=?gb2312?B?MTIzMTIzxOO6wzEyMzEyMw==?=
Date: Sun, 26 Nov 2006 19:01:04+0800
MIME-Version: 1.0
Content-Type:multipart/alternative;
    boundary="----=_NextPart_000_0003_01C7118D.38E01920"
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft OutlookExpress 6.00.2900.2869
X-MimeOLE: Produced ByMicrosoft MimeOLE V6.00.2900.2962

This is a multi-part message in MIME format.

------=_NextPart_000_0003_01C7118D.38E01920
Content-Type: text/plain;
   charset="gb2312"
Content-Transfer-Encoding:base64

MTIzMTIzMTIz

------=_NextPart_000_0003_01C7118D.38E01920
Content-Type: text/html;
   charset="gb2312"
Content-Transfer-Encoding:base64

PCFET0NUWVBFIEhUTUwgUFVCTElDICItLy9XM0MvL0RURCBIVE1MIDQuMCBUcmFuc2l0aW9uYWwv
L0VOIj4NCjxIVE1MPjxIRUFEPg0KPE1FVEEgaHR0cC1lcXVpdj1Db250ZW50LVR5cGUgY29udGVu
dD0idGV4dC9odG1sOyBjaGFyc2V0PWdiMjMxMiI+DQo8TUVUQSBjb250ZW50PSJNU0hUTUwgNi4w
MC4yOTAwLjI5OTUiIG5hbWU9R0VORVJBVE9SPg0KPFNUWUxFPjwvU1RZTEU+DQo8L0hFQUQ+DQo8
Qk9EWSBiZ0NvbG9yPSNmZmZmZmY+DQo8RElWPjxGT05UIHNpemU9Mj4xMjMxMjMxMjM8L0ZPTlQ+
PC9ESVY+PC9CT0RZPjwvSFRNTD4NCg==

------=_NextPart_000_0003_01C7118D.38E01920--

这封Email具有一个邮件首部,然后是邮件的主体部分,它包括一个文本和一个HTML类型。可以注意到这样一行编码“boundary="----=_NextPart_000_0003_01C7118D.38E01920"”,它是用来隔离MIME邮件的各个实体部分。

在RFC2822中定义了MIME邮件首部的格式:

field-name ":" [ field-body ] CRLF
例如:
MIME-Version: 1.0
Content-Type: multipart/alternative;
Content-Type: text/plain;
Content-Transfer-Encoding: base64

最常见也用途最都的MIME首部是以Content-Type开头的,在RFC2046给出了它的定义,大致与如下内容相似:
Content-Type: text/plain;
Content-Type: text/plain; charset=ISO-8859-1
Content-Type: text/plain; charset=us-ascii
Content-Type: text/plain; charset=utf-8
Content-Type: text/html;
Content-Type: text/html; charset=ISO-8859-1
Content-Type: text/css
Content-Type: image/gif; name=image004.gif
Content-Type: image/jpeg; name="image005.jpg"
Content-Type: message/delivery-status
Content-Type: message/rfc822
Content-Type: audio/x-mpeg
Content-Type: video/mpeg-2
Content-Type: application/msword
Content-Type: application/mspowerpoint
Content-Type: application/zip

Content-Type:multipart/mixed;    boundary="----=_Part_3431_12384933.1139387792352"
Content-Type: multipart/alternative;boundary="----=_Part_4088_29304219.1115463798628"
Content-Type:multipart/related;    boundary="----=_Part_2067_9241611.1139322711488"
Content-Type:multipart/digest;    boundary="----=Next message 15543233913938263541"
Content-Type: multipart/report; report-type=delivery-status;
             boundary="k04G6HJ9025016.1136391237/carbon.singnet.com.sg"
Content-Type: multipart/parallel


1) Content-Type: multipart/mixed
它表明这封Email邮件中包含各种格式的MIME实体但没有具体给出每个实体的类型。

2) Content-Type: multipart/alternative
如果同一封Email邮件既以文本格式又以HTML格式发送,那么要使用Content-Type:multipart/alternative。这两种邮件格式实际上是显示同样的内容但是具有不同的编码。

3) Content-Type: multipart/related
用于在同一封邮件中发送HTML文本和图像或者是其他类似类型。

邮件主体的编码:

主要是包括quoted-printable与base64两种类型的编码。Base64和Quoted-Printable都属于MIME(多用途部分、多媒体电子邮件和WWW 超文本)的一种编码标准,用于传送诸如图形、声音和传真等非文本数据)。
一.Base64
  Base64是现今在互联网上应用最多的一种编码,绝大多数的电子邮件软件头把它作为默认的二进制编码,比如我们常用的Outlook。
Base64内容传输编码被设计用于以人无法可读的方式来表述八位组的任意序列。编码与解码算法很简单,但是编码数据总是比非编码数据长33%。这种编码实际上类似于RFC1421中定义的在增强保密邮件(PEM)应用程序中使用的编码方式。
  编码程序将字符流顺序放入一个 24位的缓冲区,缺字符的地方补零。从左到右,一个24位输入组通过级联3个八位输入组组成。随后这24位截断成为 4 个部分,每个部分 6位,分别被翻译为base64字母表中的一个单独数字。当通过Base64编码一个位流时,位流必须假设为以最高有效位优先的顺序排列。也就是说,流中的第一位将是第一字节中的高端位,而第八位则位第一字节中的低端字节位。
  如果输入数据不足24个字符,即只有一个或两个字节时,则需要经过特殊处理——在数据末尾填充"="字符,这可以隔断附加的信息造成编码的混乱。
在Base64编码数据中,任何在Base64字母表之外的字符将被忽略。Base64编码中的非法字符序列也将被忽略,例如"=====".
二.Quoted-Printable
   Quoted-Printable与Base64一样,常常用在Email系统中。它通常用于少量文本方式的8位字符的编码,例如Foxmail就用它做对主题和信体的编码。这种编码的应该是很好辨认的:它有大量的'='。
  QP的算法非常的简单但是编码效率很低(1:3),它是专门为了处理8位字符制定的。它的算法是:读一个字符,如果ASCII码大于127,即字符的第8位是1的话,进行编码,否则忽略(有时也对7位字符编码)。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
简单的控制台程序 主要是为了学习之用 本人花时间编写。为了和大家分享和学习用,如有什么错误或认为本人哪里处理不当 请和我联系~~ 内容: main.cpp 就一个cpp文件 //1.首先需要连接邮件服务器 这里用socket 邮件服务器端口 25 //2.现在就是和服务器对话了 //3.结束 #include #include #include #include #include #include #include #include #include #include #include #include #pragma comment(lib,"WS2_32.lib") using namespace std; /*加附件的版本*/ //base64编码 string Base64Encode(LPCTSTR lpszSrc); //base64解码 string Base64Decode(LPCTSTR lpszSrc); //读文件数据 bool ReadFromFile(const char* pszFilename,string &filename); unsigned char* m_pbText; int main() { //1.首先需要连接邮件服务器 这里用socket 邮件服务器端口 25 WSADATA Wsa; //进行WINSOCK的设置 WSAStartup(0x0101,&Wsa); SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); SOCKADDR_IN sin; LPHOSTENT lphost = gethostbyname("smtp.163.com");//这里是用网易的邮件服务器 也可以修改 if(lphost) sin.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr; else { printf("%s\n","获取地址失败"); return 1; } sin.sin_family = AF_INET; //注意邮件服务器的侦听端口 25 sin.sin_port = htons(IPPORT_SMTP); //连接服务器 if(connect(s,(LPSOCKADDR)&sin,sizeof(sin))==SOCKET_ERROR) { printf("%s\n","连接错误"); return 1; } printf("%s\n","连接成功"); //接收服务器初次回应 char buff[1024]; memset(buff,0,sizeof(buff)); recv(s,buff,sizeof(buff),0); printf("服务说:%s\n",buff); /////上面已经完成连接了///// string szLine="\r\n";//相当于你按下回车 //2.现在就是和服务器对话了 //问候服务器 string szHelo = "HELO smtp.163.com" + szLine; printf("我说:%s\n",szHelo.c_str()); send(s,szHelo.c_str(),szHelo.length(),0); memset(buff,0,sizeof(buff)); recv(s,buff,sizeof(buff),0); printf("服务说:%s\n",buff); //请求验证用户密码(需要编码) string szAL = "auth login" + szLine; //发送验证命令 printf("我说:%s\n",szAL.c_str()); send(s,szAL.c_str(),szAL.length(),0); memset(buff,0,sizeof(buff)); recv(s,buff,sizeof(buff),0); // printf("服务说:%s\n",buff); //服务器会回答说 可以输入帐号 //发送帐号 string szUser; .... 具体自己下载运行即可 装个VC6.0 即可

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值