smtp 协议 MIME协议

简介:

SMTP是一种提供可靠且有效的电子邮件传输的协议。SMTP是建立在FTP文件传输服务上的一种邮件服务,主要用于系统之间的邮件信息传递,并提供有关来信的通知。SMTP独立于特定的传输子系统,且只需要可靠有序的数据流信道支持,SMTP的重要特性之一是其能跨越网络传输邮件,即“SMTP邮件中继”。使用SMTP,可实现相同网络处理进程之间的邮件传输,也可通过中继器或网关实现某处理进程与其他网络之间的邮件传输

SMTP是一个相对简单的基于文本协议。在其之上指定了一条消息的一个或多个接收者(在大多数情况下被确认是存在的),然后消息文本会被传输。可以很简单地通过telnet程序来测试一个SMTP服务器。SMTP使用TCP端口25,由于这个协议开始是基于纯ASCII文本的,它在二进制文件上处理得并不好。诸如MIME的标准被开发来编码二进制文件以使其通过SMTP来传输。今天,大多数SMTP服务器都支持8位MIME扩展,它使二进制文件的传输变得几乎和纯文本一样简单。 

 

工作过程

SMTP协议的工作过程可分为如下3个过程: 

(1)建立连接:在这一阶段,SMTP客户请求与服务器的25端口建立一个TCP连接。一旦连接建立,SMTP服务器和客户就开始相互通告自己的域名,同时确认对方的域名。 

(2)邮件传送:利用命令,SMTP客户将邮件的源地址、目的地址和邮件的具体内容传递给SMTP服务器,SMTP服务器进行相应的响应并接收邮件。 

(3)连接释放:SMTP客户发出退出命令,服务器在处理命令后进行响应,随后关闭TCP连接。 

 

SMTP缺点

1)        命令过于简单,没提供认证等功能。

2)        只传送7位的ASCII码,不能传送二进制文件。

针对缺点1),标准化组织制定了扩充的SMTP(即ESMTP),对应的RFC文档为RFC1425。

针对缺点2),标准化组织在兼容SMTP的前提下,提出了传送非7位ASCII码的方法,对应的RFC文档有两个:邮件首部的扩充对应于RFC1522,邮件正文的扩充对应与RFC1521(即MIME)。

 

常用指令


SMTP中包含一些基本的命令用于客户端和服务器端进行交互,现列出一些常见的指令:

  • HELO <domain> <CRLF>。向服务器标识用户身份发送者能欺骗,说谎,但一般情况下服务器都能检测到。
  • AUTH LOGIN  使用AUTH LOGIN与服务器进行登录验证
  • MAIL FROM: <reverse-path> <CRLF>。<reverse-path>为发送者地址,此命令用来初始化邮件传输,即用来对所有的状态和缓冲区进行初始化。
  • RCPT TO:<forward-path> <CRLF>。 <forward-path>用来标志邮件接收者的地址,常用在MAIL FROM后,可以有多个RCPT TO。
  • DATA <CRLF>。将之后的数据作为数据发送,以<CRLF>.<CRLF>标志数据的结尾。

 

  • FROM    发信人显示信息(此处可以伪造身份,但是非常容易被识别)
  • TO         收件人显示信息
  • SUBJECT    邮件基本信息:邮件标题,不填写也往往容易被定位为垃圾邮件
  • REST <CRLF>。重置会话,当前传输被取消。
  • NOOP <CRLF>。要求服务器返回OK应答,一般用作测试。
  • QUIT <CRLF>。结束会话。
  • VRFY <string> <CRLF>。验证指定的邮箱是否存在,由于安全方面的原因,服务器大多禁止此命令。
  • EXPN <string> <CRLF>。验证给定的邮箱列表是否存在,由于安全方面的原因,服务器大多禁止此命令。
  • HELP <CRLF>。查询服务器支持什么命令


常见指令返回码说明

 

  • 211系统状态或系统帮助响应
  • 214帮助信息
  • 220<domain>服务就绪
  • 221<domain>服务关闭
  • 235    认证通过
  • 250要求的邮件操作完成
  • 251用户非本地,将转发向<forward-path>
  • 354 开始邮件输入,以"."结束,发送开始,往往与data指令结合
  • 421<domain>服务未就绪,关闭传输信道
  • 450要求的邮件操作未完成,邮箱不可用
  • 451放弃要求的操作;处理过程中出错
  • 452系统存储不足,要求的操作未执行
  • 500 指定错误
  • 501参数格式错误
  • 502命令不可实现
  • 503错误的命令序列
  • 504命令参数不可实现
  • 550要求的邮件操作未完成,邮箱不可用
  • 551用户非本地,请尝试<forward-path>
  • 552过量的存储分配,要求的操作未执行
  • 553邮箱名不可用,要求的操作未执行
  • 554操作失败

 

通讯流程示例 

[root@platform ~]# telnet smtp.163.com 25
Trying 123.125.50.134...
Connected to smtp.163.com.
Escape character is '^]'.
220 163.com Anti-spam GT for Coremail System (163com[20141201])
HELO liumiao
250 OK
AUTH LOGIN
334 dXNlcm5hbWU6
ZGV2b3BzYWRtaW4=
334 UGFzc3dvcmQ6
密码的base64编码
235 Authentication successful
MAIL FROM:<devopsadmin@163.com>
250 Mail OK
RCPT TO:<liumiaocn@outlook.com>
250 Mail OK
DATA
354 End data with <CR><LF>.<CR><LF>
FROM: devopsadmin@163.com
To: liumiaocn@outlook.com
Subject: confirm information
Hi, Michael

I got your message.
Looking forward to meeting you.

Thanks & Best Regards.
.
250 Mail OK queued as smtp4,DtGowAAHhSrBwV5bL3XJAA--.5571S2 1532936690
Connection closed by foreign host.
[root@platform ~]#

报文以只有一个“.”的行结束

 

注意事项


输入AUTH LOGIN之后需要输入用户名和密码进行登录,登录时注意如下事项

  • 登录名称为@之前的内容的base64编码,比如devopsadmin@163.com为devopsadmin的base64编码

base64编码基本等于明码,但是使用的过程中请注意是否包含回测换行符号,比如devopsadmin的base64编码生成:echo -n “devopsadmin” |base64

  • 密码不是邮箱的密码,网易的话专门还有一个密码,请注意
  • 邮件发送往往服务器端需要做设定,请确认相关的邮件服务器
  • 垃圾邮件不同的邮件系统判断标准不同,一般正确将全部信息填完基本没有问题

 

base64编码的换行


请注意看一下如下代码包含换行与否的情况,认证通不过的时候,请注意检查

[root@platform ~]# echo -n "devopsadmin" |base64
ZGV2b3BzYWRtaW4=
[root@platform ~]# echo "ZGV2b3BzYWRtaW4=" |base64 -d
devopsadmin[root@platform ~]# 
[root@platform ~]# 
[root@platform ~]# echo "devopsadmin" |base64
ZGV2b3BzYWRtaW4K
[root@platform ~]# echo "ZGV2b3BzYWRtaW4K" |base64 -d
devopsadmin
[root@platform ~]# 
 

 

邮件报文的封装和报文格式

SMTP协议可以将互联网邮件报文封装在邮件对象中。SMTP协议的邮件对象由两个部分组成:信封和内容。

  • 信封实际上是一种SMTP命令。
  • 邮件报文是邮件对象中的内容,它又有首部和主体两个部分。
    如下图就是一个邮件对象的组成的示例:

这里写图片描述

下面是写进了RFC文档的对报文格式的定义: 
 1. 所有报文都是由ASCII码组成
 2. 报文由报文行组成,各行之间用回车(CR)、换行(LF)符分隔
 3. 报文的长度不能超过998个字符
 4. 报文行的长度≤78个字符之内(不包括回车换行符)
 5. 报文中可包括多个首部字段和首部内容
 6. 报文可包括一个主体,主体必须用一个空行与其首部分隔
 7. 除非需要使用回车与换行符,否则报文中不使用回车与换行符

 

 

SMTP协议的扩展协议:MIME 

MIME不属于一个邮件传输协议,它只是对SMTP的一个扩展,不能替代SMTP协议,至于为啥要替换SMTP了。主要是因为SMTP协议在传输报文时,只能够传输7位的ASCII格式的报文,不支持那些不使用7位ASCII格式的语种,同时它也不支持语音和视频数据的传输,因此我们需要一个辅助性协议帮忙传输报文,它就是MIME。

MIME协议定义了5种头部,用来加在原始的STMP头部,以便定义参数的转换。他们分别是:

 
 1. MIME-Version:MIME版本
 2. Content-Type:内容类型
 3. Content-Tansfer-Encoding:内容传输编码
 4. Content-ID:内容标识
 5. Content-Description:内容描述

这里写图片描述

 

MIME 常见的类型:application、audio、image、message、text、video、x-world   详见:http://www.w3school.com.cn/media/media_mimeref.asp

  multipart类型
       MIME邮件中各种不同类型的内容是分段存储的,各个段的排列方式、位置信息都通过Content-Type域的multipart类型来定义。multipart类型主要有三种子类型:mixedalternativerelated
       ●  multipart/mixed类型
        如果一封邮件中含有附件,那邮件的Content-Type域中必须定义multipart/mixed类型,邮件通过multipart/mixed类型中定义的boundary标识将附件内容同邮件其它内容分成不同的段。基本格式如下:
Content-Type: multipart/mixed;
                 boundary="{分段标识}"


       ●  multipart/alternative类型
        MIME邮件可以传送超文本内容,但出于兼容性的考虑,一般在发送超文本格式内容的同时会同时发送一个纯文本内容的副本,如果邮件中同时存在纯文本和超文本内容,则邮件需要在Content-Type域中定义multipart/alternative类型,邮件通过其boundary中的分段标识将纯文本、超文本和邮件的其它内容分成不同的段。基本格式如下:
Content-Type: multipart/alternative;
                 boundary="{分段标识}"


        ●  multipart/related类型
         MIME邮件中除了可以携带各种附件外,还可以将其它内容以内嵌资源的方式存储在邮件中。比如我们在发送html格式的邮件内容时,可能使用图像作为 html的背景,html文本会被存储在alternative段中,而作为背景的图像则会存储在multipart/related类型定义的段中。基本格式如下:
Content-Type: multipart/related;
                 type="multipart/alternative";
                 boundary="{分段标识}"


  multipart类型的boundary属性
  multipart的子类型中都定义了各自的boundary属性,邮件使用这些boundary中定义的字符串作为标识,将邮件内容分成不同的段,段体内的每个子段以“--”+boundary行开始,父段则以“--”+boundary+“--”行结束,不同段之间用空行分隔。

 

 

SMTP安全和垃圾邮件

最初的SMTP的局限之一在于它没有对发送方进行身份验证的机制。因此,后来定义了SMTP-AUTH扩展。

尽管有了身份认证机制,垃圾邮件仍然是一个主要的问题。但由于庞大的SMTP安装数量带来的网络效应,大刀阔斧地修改或完全替代SMTP被认为是不现实的。Internet Mail 2000就是一个替代SMTP的建议方案。

因此,出现了一些同SMTP工作的辅助协议。IRTF的反垃圾邮件研究小组正在研究一些建议方案,以提供简单、灵活、轻量级的、可升级的源端认证。最有可能被接受的建议方案是发件人策略框架协议。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 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 即可
该压缩包包含三个文档,分别是SMTP协议详解,POP3协议详解,MIME规范详解,文档中详细介绍了一个邮件发送和接收的过程分析,协议本身的包含的命令和工作过程,为开发邮件代理的客户端提供技术基础。如下是部分SMTP协议部分内容: 1.1 SMTP在邮件通信中的位置 SMTP,即简单邮件传送协议,所对应RFC文档为RFC821。同http等多数应用层协议一样,它工作在C/S模式下,用来实现因特网上的邮件传送。SMTP在整个电子邮件通信中所处的位置。可以看出,SMTP是用来将客户机上的邮件传送到服务器上。这里的客户机是指某次连接中的发送方,服务器是指相应的接收方。在讲解发送邮件的整个通信过程前,先解释一下面几个术语。 1.2几个术语 1.2.1.邮件 邮件是一种消息的格式,由信封、首部和正文组成。 信封上最重要的是收信人的地址。邮件服务器用这个地址将邮件发送到收信人所在的邮件服务器上。 首部是由用户代理或邮件服务器添加的一些信息。包括Received、Message-ID、From、Data、Reply-To、X-Phone、X-Mailer、To和Subject等字段。 正文是是发送用户发给接收用户报文的内容。RFC 822 规定正文为NVT ASCII文字行。 更为详细的说明,请参考RFC821和RFC822等协议。 1.2.2.用户代理 用户代理UA(User Agent)是用户与电子邮件系统的交互接口,一般来说它就是我们PC机上的一个程序。Windows上常见的用户代理是Foxmail和Outlook Express。 用户代理提供一个好的用户界面,它提取用户在其界面填写的各项信息,生成一封符合SMTP等邮件标准的邮件,然后采用SMTP协议将邮件发送到发送端邮件服务器。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值