标题：SMTP协议
SMTP协议简介
SMTP目前已是事实上的在Internet传输E-Mail的标准，是一个相对简单的基于文本的协议。在其之上指定了一条消息的一个或多个接收者（在大多数情况下被确定是存在的），然后消息文本就传输了。可以很简单地通过Telnet程序来测试一个SMTP服务器，SMTP使用TCP端口25。要为一个给定的域名决定一个SMTP服务器，需要使用MX(Mail eXchange）DNS。
SMTP协议发展在20世纪80年代早期SMTP开始被广泛地使用。当时它只是作为UUCP的补充，UUCP更适合于处理在间歇连接的机器间传送邮件。相反SMTP在发送和接收的机器始终都联网的情况下工作得最好。
SMTP独立于特定的传输子系统，且只需要可靠有序的数据流信道支持。SMTP重要特性之一是其能跨越网络传输邮件，即“SMTP邮件中继”。通常，一个网络可以由公用因特网上TCP可相互间访问的主机、防火墙分隔的TCP/IP网络上TCP可相互访问的主机，以及其他LAN/WAN中的主机利用非TCP传输层协议组成。使用SMTP，可实现相同网络上处理机之间的邮件传输，也可通过中继器或网关是实现某处理机与其他网络之间的邮件传输。SMTP的作用：在smtp这种方式下，邮件的发送可能经过从发送端到接收端路径上的大量中间中继器或网关主机。域名服务系统（ DNS)的邮件交换服务器可以用来识别出传输邮件的下一跳IP地址。
Sendmail是最早实现SMTP的邮件传输代理之一。到2001年至少有50个程序将SMTP 实现为一个客户端（消息的发送者）或一个服务器（消息的接受者）。一些其他的流行的SMTP服务器包括Philip Hazel 的exim，IBM的Postfix，D.J.Bernstein的Qmail，以及Microsoft Exchange Server.
由于这个协议开始是基于纯ASCⅡ文本的，在二进制文件上处理得并不好。后来开发了用来编码二进制文件的标准，如MIME，以使其通过SMTP来传输。今天，大多数SMTP服务器都支持8位MIME扩展，它使二进制文件的传输变得几乎和纯文本一样简单。
( 注意：SMTP是一个"推"的协议，它不允许根据需要从远程服务器上“拉”来消息。要做到这点，邮件客户端必须使用POP3或IMAP上。另一个，SMTP服务器可以使用ETRN(Extended Turn，扩展回车）命令在SMTP上触发一个发送。)SMTP协议的局限：垃圾邮件仍然是个重要的问题。原始的SMTP协议的局限之一在于它没有为发送方进行认证的功能。因此定义了SMTP-AUTH 扩展。由于SMTP 巨大安装基础的网络效应，广阔地修改SMTP或者完全替代它被认为是不现实的。Internet Mail 2000 就是这样一个为替换而做的建议。IRTF 的反垃圾邮件研究小组正在研究一些提供简单、灵活、轻量级的、可升级的源端认证的建议。最有可能被接受的建议是Sender Policy Framework 协议。
SMTP协议命令及工作原理：
SMTP命令：SMTP命令是发送于SMTP主机之间的ASCⅡ信息，可能使用到的命令如下表所示。
SMTP协议命令
命令描述DATA开始信息写作EXPN<string>验证给定的邮箱列表是否存在，扩充邮箱列表，也常被禁用HELO<domain>向服务器标识用户身份，返回邮件服务器身份HELP<command>查询服务器支持什么命令，返回命令中的信息MAIL FROM<host>在主机上初始化一个邮件会话NOOP无操作，服务器应响应OKQUIT终止邮件会话RCPT TO<user>标识单个的邮件接收人；常在MAIL命令后面可有多个rcpt to：RSET重置会话，当前传输被取消SAML FROM<host>发送邮件到用户终端和邮箱SEND FROM<host>发送邮件到用户终端SOML FROM<host>发送邮件到用户终端或邮箱TURN接收端和发送端交换角色VRFY<user>用于验证指定的用户/邮箱是否存在；由于安全方面的原因，服务器常禁止此命令
SMTP协议工作原理：SMTP是工作在两种情况下：一是电子邮件从客户机传输到服务器：二是从某一个服务器传输到另一个服务器。SMTP也是个请求/响应协议，命令和响应都是基于ASCⅡ文本，并以CR和LF符结束。响应包括一个表示返回状态的三位数字代码。SMTP在TCP协议25号端口监听连续请求。
smtp连接和发送过程：（1）建立TCP 连接。
（2）客户端发送HELO命令以标识发件人自己的身份，然后客户端发送MAIL命令；服务器端正希望以OK作为响应，表明准备接收。
（3）客户端发送RCPT命令，以标识该电子邮件的计划接收人，可以有多个RCPT行；服务器端则表示是否愿意为收件人接收邮件。
（4）协商结束，发送邮件，用命令DATA发送。
（5）以“.”号表示结束输入内容一起发送出去，结束此次发送，用QUIT命令退出。
SMTP协议的邮件路由过程及个人SMTP邮件服务器简单配置SMTP协议的邮件路由过程：SMTP服务器基于域名服务DNS中计划收件人的域名来路由电子邮件。SMTP服务器基于DNS中的MX记录来路由电子邮件，MX记录注册了域名和相关的SMTP中继主机，属于该域的电子邮件都应向该主机发送。若SMTP服务器 mail.abc.com 收到一封信要发到shuer@sh.abc.com，则执行以下过程：
（1）Sendmail 请求DNS给出主机sh.abc.com的CNAME 记录，如有，假若CNAME（别名记录）到shmail.abc.com，则再次请求shmail.abc.com的CNAME记录，直到没有为止。
（2）假定被CNAME到shmail.abc.com，然后sendmail请求@abc.com 域的DNS给出shmail.abc.com的MX记录（邮件路由及记录），shmail MX 5 shmail.abc.com 10 shmail2.abc.com。
（3）Sendmail组合请求DNS给出shmail.abc.com的A记录（主机名（或域名）对应的IP地址记录），即IP地址，若返回值为1.2.3.4（假设值）。
（4）Sendmail与1.2.3.4连接，传送这封给shuser@sh.abc.com 的信到1.2.3.4 这台服务器的SMTP后台程序。
个人SMTP邮件服务器简单配置：一、安装POP3和SMTP服务组件  
Windows Server 2003默认情况下是没有安装POP3和SMTP服务组件的，因此我们要手工添加。  
1.安装POP3服务组件  
以系统管理员身份登录Windows Server 2003 系统。依次进入“控制面板→添加或删除程序→添加/删除Windows组件”，在弹出的“Windows组件向导”对话框中选中“电子邮件服务”选项，点击“详细信息”按钮，可以看到该选项包括两部分内容：POP3服务和POP3服务Web管理。为方便用户远程Web方式管理邮件服务器，建议选中“POP 3服务Web管理”。  
2.安装SMTP服务组件  
选中“应用程序服务器”选项，点击“详细信息”按钮，接着在“Internet信息服务（IIS）”选项中查看详细信息，选中“SMTP Service”选项，最后点击“确定”按钮。此外，如果用户需要对邮件服务器进行远程Web管理，一定要选中“万维网服务”中的“远程管理（HTML）”组件。完成以上设置后，点击“下一步”按钮，系统就开始安装配置POP3和SMTP服务了。  
二、配置POP3服务器  
1.创建邮件域  
点击“开始→管理工具→POP3服务”，弹出POP3服务控制台窗口。选中左栏中的POP3服务后，点击右栏中的“新域”，弹出“添加域”对话框，接着在“域名”栏中输入邮件服务器的域名，也就是邮件地址“@”后面的部分，如“MAIL.COM”，最 后点击“确定”按钮。  
2.创建用户邮箱  
选中刚才新建的“MAIL.COM”域，在右栏中点击“添加邮箱”，弹出添加邮箱对话框，在“邮箱名”栏中输入邮件用户名，然后设置用户密码，最后点击“确定”按钮，完成邮箱的创建。  
三、配置SMTP服务器  
完成POP3服务器的配置后，就可开始配置SMTP服务器了。点击“开始→程序→管理工具→Internet信息服务（IIS）管理器”，在“IIS管理器”窗口中右键点击“默认SMTP虚拟服务器”选项，在弹出的菜单中选中“属性”，进入“默认SM TP虚拟服务器”窗口，切换到“常规”标签页，在“IP地址”下拉列表框中选中邮件服务器的IP地址即可。点击“确定”按钮，此时SMTP服务器默认的是匿名访问，打开切换到“访问”标签页，点击“身份验证”按钮，在对话框中去掉“匿名访问“选项，选中”基本身份验证（Basic authentication）“。这样一个简单的邮件服务器就架设完成了。[1]
SMTP服务扩展
smtp服务的意义：SMTP提供一种可靠的有效的传送机制，它用于传送电子邮件。虽然十几年来，它的作用已经有目共睹，可是对它功能的扩充也是必不可少的。对SMTP服务的扩展我们介绍一下：在SMTP转发的邮件中包括信封和内容这两种东西。我们写信也写信封和信皮，我们可以借生活中的信件来帮助理解。
(1)SMTP信封比较容易理解，它被作为一系列的SMTP协议单元传送，它包括发送者地址，传送模式，还有一个或多个接收者地址。如果有不清楚的地方，请参阅《SMTP协议标准》。
(2)至于内容，它是由两部分组成的，一部分是信头，一部分是信体，信头是由一个个的域/值对（一个域，一个值）组成的，如果信体有结构的话，它的结构是以MIME构造的。内容从根本上来说是文本的，一般也是由ASCII码构成的，但是由于使用了MIME，所以这个限制应该也是没有了，但信头却不行，一般都应该使用ASCII码表示。虽然SMTP协议是一个不错的协议，可是对它的扩展还是不可避免，本文主要说明了一种扩展方法，使用这种扩展方法，服务器和用户之间可以相互知道对方使用了扩展，使用了多少，如果进行通信。
这里我们希望让大家知道网络协议中的一个经验：参数越多，死得越快；参数越少，越能持久。参数太多了，根本不利于使用，无法推广，早晚会被别的协议取代。这也符合科学的基础原理，简单。这说明在实现时一定要小心，如果不小心会便得到的远远小于付出的，有时根本不能提供任何益处。
EHLO命令：支持SMTP服务扩展的客户应该以EHLO命令开始SMTP会话，而不是通常的HELO命令。如果服务器也支持，那就返回确认响应，如果不支持就返回失败响应。因为引入了EHLO命令，因此会话开始的第一条命令可以是HELO或EHLO。
因此引入了新的参数，所以SMTP的MAILFROM和RCPTTO命令行长度也能再是512字节了，但是引入新参数的长度必须加以说明，以便实现者准备缓冲区。
命令格式如下：
ehlo-cmd::="EHLO"SPdomainCRLF
在命令成功是，服务器返回代码250，如果失败返回代码550，如果出错，返500，501，502，504或421。对比《SMTP协议标准》，EHLO命令可以出现在任何HELO命令出现的地方，在成功发送一个HELO或EHLO命令后再次发送它会使服务器返回503。客户这时不能缓存服务器返回的任何信息。这里一定要注意的是，每次开始SMTP扩展服务会话的时候必须发送EHLO命令。如果服务器能够处理EHLO命令，它会返回代码250。这样，服务器和客户就处于初始状态了，也就是说，所有的状态表和缓冲区已经准备完毕。通常这种响应是多行的，每行响应包括一个关键字，如果有的话，还有一个或多个参数，响应的语法如下：
ehlo-ok-rsp::="250"domain[SPgreeting]CRLF
/("250-"domain[SPgreeting]CRLF
*("250-"ehlo-lineCRLF)
"250"SPehlo-lineCRLF)
greeting::=1*<除了CR或LF的所有字符>
ehlo-line::=ehlo-keyword*(SPehlo-param)
ehlo-keyword::=(字母/数字)*(字母/数字/"-")
ehlo-param::=1*<随了空格和控制字符外的字符>
ALPHA::=<大写A到Z，小写A到Z>
DIGIT::=<0到9>
CR::=<回车，ASCII码13>
LF::=<换行，ASCII码10>
SP::=<空格，ASCII码32>
虽然EHLO关键字可以是大写，小写，大小写混合的，但是对它的处理是大小写敏感的，这是与原来规定不同的。IANA支持SMTP服务扩展注册，相对于每个扩展都有一个相应的EHLO关键字值，每个在IANA注册的服务扩展必须在一个RFC中定义。如果一个关键字以X开头，它指的是这个服务扩展是双方约定的，不是标准的。
如果出于某种原因，服务器不能列出它所支持的服务扩展，就返回代码554。在接收到这个代码后，客户要么发送HELO，要么发送QUIT命令。有时候服务器接收到EHLO命令，可是命令参数不可接受，它就返回代码501。如果服务器识别了EHLO，但对服务器扩展未实现，则返回代码502。
如果服务器不再提供服务扩展，则返回代码421。在接收到这个代码后，客户要么发送HELO，要么发送QUIT命令。如果服务器不支持服务扩展，则返回500，服务器保持现有状态，在接收到这个代码后，客户要么发送HELO，要么发送QUIT命令。
有时候，SMTP服务器会在接收到EHLO命令后因为某种原因关闭连接，这种情况在原来的SMTP协议标准中未涉及。为了处理这种情况，客户必须能够确认服务器是否能够工作，它可以重新连接并发送HELO或EHLO命令。有些服务器在接收到一个EHLO命令后会拒绝接收新的HELO命令，这时可以利用RSET命令重新启动，然后再发送HELO。如果客户不注意这样的小细节，会收到失败代码。
下面我们来看一下MAILFROM和RCPTTO参数。许多服务扩展是在MAILFROM和RCPTTO命令后加入一些参数来实现的。下面我们看一下这两个命令的格式：
esmtp-cmd::=inner-esmtp-cmd[SPesmtp-parameters]CRLF
esmtp-parameters::=esmtp-parameter*(SPesmtp-parameter)
esmtp-parameter::=esmtp-keyword["="esmtp-value]
esmtp-keyword::=(字母/数字)*(字母/数字/"-")
esmtp-value::=1*<除了空格，"="和控制字符的所有字符>
inner-esmtp-cmd::=("MAILFROM:"返回路径)/("RCPTTO:"转发路径)
如果服务器不能识别或实现一个或多个MAILFROM或RCPTTO参数，它应该返回代码555。如果这种情况只是暂时的，服务器返回代码455。其它返回代码请查阅相关资料，这里不再详述了。服务器以服务扩展处理时，它处理的任何信息都应该在包头上加上“服务扩展标记”以示区别。
下面是一个例子：
(1)双方交互：S是服务器，C是客户。
S:<等待连接在TCP端口25>
C:<连接到服务器>
S:220dbc.mtview.ca.usSMTPserviceready
C:EHLOymir.claremont.edu
S:250dbc.mtview.ca.ussayshello
...
(2)下面也是一个例子：
S:<等待连接在TCP端口25>
C:<连接到服务器>
S:220dbc.mtview.ca.usSMTPserviceready
C:EHLOymir.claremont.edu
S:250-dbc.mtview.ca.ussayshello
S:250-EXPN
S:250-HELP
S:250-8BITMIME
S:250-XONE
S:250XVRB
...
这说明服务器实现了服务扩展EXPN和HELP，这两个是标准的服务扩展，另外两个以X开头的是非标准的。　
(3)最后，我们来看看服务器不支持服务扩展时的情况：
S:<等待连接在TCP端口25>
C:<连接到服务器>
S:220dbc.mtview.ca.usSMTPserviceready
C:EHLOymir.claremont.edu
S:500Commandnotrecognized:EHLO
...
代码500表示服务器不支持服务扩展。