电子邮件是因特网上最为流行的应用之一如同邮递员分发投递传统邮件一样电子邮件也是异步的也就是说人们是在方便的时候发送和阅读邮件的无须预先与别人协同与传统邮件不同的是电子邮件既迅速又易于分发而且成本低廉另外现代的电子邮件消息可以包含超链接HTML格式文本图像声音甚至视频数据我们将在本文中查看处于因特网电子邮件核心地位的应用层协议但在深入讨论这些协议之前让我们先概览一下因特网邮件系统及其重要部件
下图展示了因特网邮件系统的高层概貌我们看到该系统由三类主要部件构成:用户代理邮件服务器利简单邮件传送协议(simple Mail Transfer Protocol简称SMTP)我们将在这样的上下文中说明每类部件:发信人Aice给收传人Bob发送一个电于邮件消息用户代理允许用户阅读回复转寄保存和编写邮件消息(电子邮件的用户代理有时称为邮件阅读器不过我们在本文中避免使用这个说法)Alice写完电子邮件消息后她的用户代理把这个消息发送给邮件服务器再由该邮件服务器把这个消息排入外出消息队列中当Bob想阅读电子邮件消息时他的用户代理将从他在其邮件服务器上的邮箱中取得邮件世纪年代后期图形用户界面(GUI)的电子邮件用户代理变得流行起来它们允许用户阅读和编写多媒体消息当前流行的用户代理包括Ootlookfoxmail等公共域中还有许多基于文本的电于邮件用户代理包括mailpine和elm
图 因特网电子邮件系统概貌
邮件服务器构成了电子邮件系统的核心每个收信人都有一个位于某个邮件服务器上的邮箱(mailbox)Bob的邮箱用于管理和维护已经发送给他的邮件消息一个邮件消息的典型旅程是从发信人的用户代理开始游经发信人的邮件服务器中转到收信人的邮件服务器然后投递到收信人的邮箱中当Bob想查看自己的邮箱中的邮件消息时存放该邮箱的邮件服务器将以他提供的用户名和口令认证他Alice的邮件服务器还得处理Bob的邮件服务器出故障酌情况如果Alice的邮件服务器无法把邮件消息立即递送到Bob的邮件服务器Aice的服务器就把它们存放在消息队列(message queue)中以后再尝试递送这种尝试通常每分钟左右执行一次:要是过了若干天仍未尝试成功该服务器就把这个消息从消息队列中去除掉同时以另一个邮件消息通知发信人(即Alice)
简单邮件传送协议(SMTP)是因特网电子邮件系统首要的应用层协议它使用由TCP提供的可靠的数据传输服务把邮件消息从发信人的邮件服务器传送到收信人的邮件服务器跟大多数应用层协议一样SMTP也存在两个端:在发信人的邮件服务器上执行的客户端和在收信人的邮件服务器上执行的服务器端SMlP的客户端和服务器端同时运行在每个邮件服务器上当一个邮件服务器在向其他邮件服务器发送邮件消息时它是作为SMTP客户在运行当一个邮件服务器从其他邮件服务器接收邮件消息时它是作为SMTP服务器在运行
SMTP
SMTP在RFC 中定义它的作用是把邮件消息从发信人的邮件服务器传送到收信人的邮件服务器SMIP的历史比HTTP早得多其RFC是在年编写的而SMTP的现实使用又在此前多年就有了尽管SMTP有许多奇妙的品质(它在因特网上的无所不在就是见证)但却是一种拥有某些古老特征的传统战术例如它限制所有邮件消息的信体(而不仅仅是信头)必须是简单的位ASCII字符格式这个限制在世纪年代早期是有意义的当时因特网传输能力不足没有人在电子邮件巾附带大数据量酌图像音频或视频文件然而到了多媒体时代的今天这个限制就多少显得局促了——它迫使二进制多媒体数据在文由SMTP传送之前首先编码成位ASCII文本;SMTP传送完毕之后再把相应的位ASCII文本邮件消息解码成二进制数据HTTP不需要对多媒体数据进行这样的编码解码操作
下面我们通过查看一个常见的情形来说明SMTP的基本操作假设Alice给Bob发送一个简单的ASCII文本邮件消息:
●Alice调用自己的电子邮件用户代理给出Bob的电子邮件地址(譬如说bob@someschooledu)写好邮件内容然后让用户代理发送本邮件消息
●Alice的用户代理把该邮件消息发送到她的邮件服务器中由邮件服务器把该消息排人某个消息队列中
●运行在Aice的邮什服务器上的SMTP客户端看到消息队列中的这个邮件消息后打开一个到运行在Bob的邮件服务器主机上的SMTP服务器端的TCP连接
●经过最初的一些SMTP握手之后SMTP客户把Aice的邮件消息发送到TCP连接上
●在Bob的邮件服务器主机上SMTP服务器收到这个邮件消息后把这个消息投递到Bob的邮箱中
●Bob在方便的时候调用自己的电子邮件用户代理阅读该邮件消息
图展示了上述情形
图 alice的邮件服务器把邮件消息传送到Bob的邮件服务器
需注意的是SMTP通常不使用中间的邮件服务器主机中转邮件即便源端和目的端邮件服务器主机位于地球上相反的位置也一样假设Aiice的邮件服务器主机在香港Bob的邮件服务器主机在阿拉巴马州那么所建立的TCP连接将是这两台服务器主机之间的连接具体地说如果Bob的邮件服务器不工作了那么Aice发给Bob的邮件消息将存留在Alice的邮件服务器中等待新的尝试而不会存放到某个中间的邮件服务器中
下面查看SWPT把邮件消息从发送端邮件服务器传送到接收端邮件服务器的具体过程我们将看到SMTP协议与人们用于面对面交互的礼仪之间有许多相似之处首先运行在发送端邮件服务器主机上的SMTP客户发起建立一个到运行在接收端邮件服务器主机上的SMTP服务器端口号之间的TCP连接如果接收邮件服务器当前不在工作SMTP客户就等待一段时间后再尝试建立该连接这个连接建立之后SMTP客户和服务器先执行一些应用层握手操作就像人们在转手东西之前往往先自我介绍那样SMTP客户和服务器也在传送信息之前先自我介绍一下在这个SMTP握手阶段SMTP客户向服务器分别指出发信人和收信人的电子邮件地址彼此自我介绍完毕之后客户发出邮件消息SMTP可以指望由TCP提供的可靠数据传输服务把该消息无错地传送到服务器如果客户还有其他邮件消息需发送到同一个服务器它就在同一个TCP连接上重复上述过程;否则它就指示TCP关闭该连接
让我们看一个客户(C)和服务器(S)交互的例子客户所在主机名为crepesfr服务器所在主机名为hamburgeredu前面标以C:的ASCII文本行是客户发送到它的TCP套接字中的完整文本行前面标以S:的ASCII文本行是服务器发送到它的TCP套接字中的完整文本行以下传输脚本在TCP连接建立之后马上发生:
S: hamburgeredu
C:HELO crepesfr
S: Hello crepesfrpleased to meet you
C:MAIL FROM:
S: alice@crepesfr Serder OK
C:RCPT TO:
S: bob@hamburgereduRecipient OK
C:DATA
S: Enter mailend with on a line by its self
C:Do you like ketchup?
C:How about pickles?
C:
S; Message accepted for delivery
C:QUIT
S: hamburgeredu cloing connection
在这个例子中客户发送了一个从邮件服务器主机crepesfr到hamburgeredu的邮件消息信体内容为:Do you like ketchup?How about pickles?客户总共发出了个命令分别为:HELOMAIL FROMRCPT TODATA和QUIT这些命令的含义是不言自明的服务器给每个命令发回应答其中每个应答都由应答码和一些英语解释(可选)构成这里需指出的是SMTP使用持久连接也就是说如果发送邮件服务器有多个邮件消息需发送到同一个接收邮件服务器那么所有这些消息可以在同一个TCP连接中发送对于其中的每一个消息客户以一个新的HELO crepesfr命令开始整个消息发送过程但是QUIT命令要等到所有消息都发送完之后才发出
我们可以尝试使用nc工具直接与SMTP服务器进行对话首先指定使用SMTP端口号连接到某台邮件服务器主机这样就在本地主机和该邮件服务器主机之间建立了一个SMTP使用的TCP连接登录完毕之后应该立即收到来服务器的应答接着就可以在合适的时刻依次发出现SMTP命令了如果你连接到你朋友的MTP服务器就可以用这种方式向你的朋友发送邮件了(也就是说不必使用邮件用户代理)当然你也可以使用更常见的telnet工具不过我发现用telnet建立起连接后常会遇到一些输入方面的问题
与HTTP的比较
我们简单地比较一下SMTP和HTTP这两个协议都是用于从一台主机向另一台主机传送文件;HTTP用于从web服务器向Web用户代理(即浏览器)传送文件(或对象)SMTP用于从一个邮件服务器向另一个邮件服务器传送文件(也就是电子邮件消息)在传送文件时SMTP和持久HTTP都使用持久连接可见这两个协议具有一些共同的特征不过它们之间的差别也是显着的首先HTTP基本上是一个内拉式协议(pull protocol)——有人把信息上传到web服务器中用户则在方便的时候使用HTTP把这些信息从服务器上拉过来更确切地说TCP连接是由想要接收文件的主机发起的SMIP则基本上是一个外推式协议(pushProtoco)——发送端邮件服务器把文件推送给接收端邮件服务器更确切地说TCP连接是由想要发送文件的主机发起的
SMTP和HTTP的第二个重要差别是SMTP要求包括信体部分在内的每个邮件消息都是位ASCII文本格式另外SMT