郵件服務(wù)器基礎(chǔ):郵件服務(wù)相關(guān)協(xié)議一
電子郵件是因特網(wǎng)上最為流行的應(yīng)用之一。如同郵遞員分發(fā)投遞傳統(tǒng)郵件一樣,電子郵件也是異步的,也就是說(shuō)人們是在方便的時(shí)候發(fā)送和閱讀郵件的,無(wú)須預(yù)先與別人協(xié)同。與傳統(tǒng)郵件不同的是,電子郵件既迅速,又易于分發(fā),而且成本低廉。另外,現(xiàn)代的電子郵件消息可以包含超鏈接、HTML格式文本、圖像、聲音甚至視頻數(shù)據(jù)。我們將在本文中查看處于因特網(wǎng)電子郵件核心地位的應(yīng)用層協(xié)議。但在深入討論這些協(xié)議之前,讓我們先概覽一下因特網(wǎng)郵件系統(tǒng)及其重要部件。
下圖展示了因特網(wǎng)郵件系統(tǒng)的高層概貌。我們看到,該系統(tǒng)由三類主要部件構(gòu)成:用戶代理、郵件服務(wù)器利簡(jiǎn)單郵件傳送協(xié)議(simple Mail Transfer Protocol,簡(jiǎn)稱SMTP)。我們將在這樣的上下文中說(shuō)明每類部件:發(fā)信人A1ice給收傳人Bob發(fā)送一個(gè)電于郵件消息。用戶代理允許用戶閱讀、回復(fù)、轉(zhuǎn)寄、保存和編寫(xiě)郵件消息(電子郵件的用戶代理有時(shí)稱為郵件閱讀器,不過(guò)我們?cè)诒疚闹斜苊馐褂眠@個(gè)說(shuō)法)。Alice寫(xiě)完電子郵件消息后,她的用戶代理把這個(gè)消息發(fā)送給郵件服務(wù)器,再由該郵件服務(wù)器把這個(gè)消息排入外出消息隊(duì)列中。當(dāng)Bob想閱讀電子郵件消息時(shí),他的用戶代理將從他在其郵件服務(wù)器上的郵箱中取得郵件。20世紀(jì)90年代后期,圖形用戶界面(GUI)的電子郵件用戶代理變得流行起來(lái),它們?cè)试S用戶閱讀和編寫(xiě)多媒體消息。當(dāng)前流行的用戶代理包括Ootlook,foxmail等。公共域中還有許多基于文本的電于郵件用戶代理,包括mail、pine和elm。
圖1 因特網(wǎng)電子郵件系統(tǒng)概貌
郵件服務(wù)器構(gòu)成了電子郵件系統(tǒng)的核心。每個(gè)收信人都有一個(gè)位于某個(gè)郵件服務(wù)器上的郵箱(mailbox)。Bob的郵箱用于管理和維護(hù)已經(jīng)發(fā)送給他的郵件消息。一個(gè)郵件消息的典型旅程是從發(fā)信人的用戶代理開(kāi)始,游經(jīng)發(fā)信人的郵件服務(wù)器,中轉(zhuǎn)到收信人的郵件服務(wù)器,然后投遞到收信人的郵箱中。當(dāng)Bob想查看自己的郵箱中的郵件消息時(shí),存放該郵箱的郵件服務(wù)器將以他提供的用戶名和口令認(rèn)證他。Alice的郵件服務(wù)器還得處理Bob的郵件服務(wù)器出故障酌情況。如果Alice的郵件服務(wù)器無(wú)法把郵件消息立即遞送到Bob的郵件服務(wù)器,A1ice的服務(wù)器就把它們存放在消息隊(duì)列(message queue)中,以后再嘗試遞送。這種嘗試通常每30分鐘左右執(zhí)行一次:要是過(guò)了若干天仍未嘗試成功,該服務(wù)器就把這個(gè)消息從消息隊(duì)列中去除掉,同時(shí)以另一個(gè)郵件消息通知發(fā)信人(即Alice)。
簡(jiǎn)單郵件傳送協(xié)議(SMTP)是因特網(wǎng)電子郵件系統(tǒng)首要的應(yīng)用層協(xié)議。它使用由TCP提供的可靠的數(shù)據(jù)傳輸服務(wù)把郵件消息從發(fā)信人的郵件服務(wù)器傳送到收信人的郵件服務(wù)器。跟大多數(shù)應(yīng)用層協(xié)議一樣,SMTP也存在兩個(gè)端:在發(fā)信人的郵件服務(wù)器上執(zhí)行的客戶端和在收信人的郵件服務(wù)器上執(zhí)行的服務(wù)器端。SMlP的客戶端和服務(wù)器端同時(shí)運(yùn)行在每個(gè)郵件服務(wù)器上。當(dāng)一個(gè)郵件服務(wù)器在向其他郵件服務(wù)器發(fā)送郵件消息時(shí),它是作為SMTP客戶在運(yùn)行。當(dāng)一個(gè)郵件服務(wù)器從其他郵件服務(wù)器接收郵件消息時(shí),它是作為SMTP服務(wù)器在運(yùn)行。
#P#SMTP
SMTP在RFC 821中定義,它的作用是把郵件消息從發(fā)信人的郵件服務(wù)器傳送到收信人的郵件服務(wù)器。SMIP的歷史比HTTP早得多,其RFC是在1982年編寫(xiě)的,而SMTP的現(xiàn)實(shí)使用又在此前多年就有了。盡管SMTP有許多奇妙的品質(zhì)(它在因特網(wǎng)上的無(wú)所不在就是見(jiàn)證),但卻是一種擁有某些“古老”特征的傳統(tǒng)戰(zhàn)術(shù)。例如,它限制所有郵件消息的信體(而不僅僅是信頭)必須是簡(jiǎn)單的7位ASCII字符格式。這個(gè)限制在20世紀(jì)80年代早期是有意義的,當(dāng)時(shí)因特網(wǎng)傳輸能力不足,沒(méi)有人在電子郵件巾附帶大數(shù)據(jù)量酌圖像、音頻或視頻文件。然而到了多媒體時(shí)代的今天,這個(gè)限制就多少顯得局促了——它迫使二進(jìn)制多媒體數(shù)據(jù)在文由SMTP傳送之前首先編碼成7位ASCII文本;SMTP傳送完畢之后,再把相應(yīng)的7位ASCII文本郵件消息解碼成二進(jìn)制數(shù)據(jù)。HTTP不需要對(duì)多媒體數(shù)據(jù)進(jìn)行這樣的編碼解碼操作。
下面我們通過(guò)查看一個(gè)常見(jiàn)的情形來(lái)說(shuō)明SMTP的基本操作。假設(shè)Alice給Bob發(fā)送一個(gè)簡(jiǎn)單的ASCII文本郵件消息:
●Alice調(diào)用自己的電子郵件用戶代理,給出Bob的電子郵件地址(譬如說(shuō)bob@someschool.edu),寫(xiě)好郵件內(nèi)容,然后讓用戶代理發(fā)送本郵件消息。
●Alice的用戶代理把該郵件消息發(fā)送到她的郵件服務(wù)器中,由郵件服務(wù)器把該消息排人某個(gè)消息隊(duì)列中。
●運(yùn)行在A1ice的郵什服務(wù)器上的SMTP客戶端看到消息隊(duì)列中的這個(gè)郵件消息后,打開(kāi)一個(gè)到運(yùn)行在Bob的郵件服務(wù)器主機(jī)上的SMTP服務(wù)器端的TCP連接。
●經(jīng)過(guò)最初的一些SMTP握手之后,SMTP客戶把A1ice的郵件消息發(fā)送到TCP連接上。
●在Bob的郵件服務(wù)器主機(jī)上,SMTP服務(wù)器收到這個(gè)郵件消息后,把這個(gè)消息投遞到Bob的郵箱中。
●Bob在方便的時(shí)候調(diào)用自己的電子郵件用戶代理閱讀該郵件消息。
圖2展示了上述情形。
圖2 alice的郵件服務(wù)器把郵件消息傳送到Bob的郵件服務(wù)器
需注意的是,SMTP通常不使用中間的郵件服務(wù)器主機(jī)中轉(zhuǎn)郵件,即便源端和目的端郵件服務(wù)器主機(jī)位于地球上相反的位置也一樣。假設(shè)Aiice的郵件服務(wù)器主機(jī)在香港,Bob的郵件服務(wù)器主機(jī)在阿拉巴馬州,那么所建立的TCP連接將是這兩臺(tái)服務(wù)器主機(jī)之間的連接。具體地說(shuō),如果Bob的郵件服務(wù)器不工作了,那么A1ice發(fā)給Bob的郵件消息將存留在Alice的郵件服務(wù)器中等待新的嘗試,而不會(huì)存放到某個(gè)中間的郵件服務(wù)器中。
下面查看SWPT把郵件消息從發(fā)送端郵件服務(wù)器傳送到接收端郵件服務(wù)器的具體過(guò)程。我們將看到,SMTP協(xié)議與人們用于面對(duì)面交互的禮儀之間有許多相似之處。首先,運(yùn)行在發(fā)送端郵件服務(wù)器主機(jī)上的SMTP客戶,發(fā)起建立一個(gè)到運(yùn)行在接收端郵件服務(wù)器主機(jī)上的SMTP服務(wù)器端口號(hào)25之間的TCP連接。如果接收郵件服務(wù)器當(dāng)前不在工作,SMTP客戶就等待一段時(shí)間后再嘗試建立該連接。這個(gè)連接建立之后,SMTP客戶和服務(wù)器先執(zhí)行一些應(yīng)用層握手操作。就像人們?cè)谵D(zhuǎn)手東西之前往往先自我介紹那樣,SMTP客戶和服務(wù)器也在傳送信息之前先自我介紹一下。在這個(gè)SMTP握手階段,SMTP客戶向服務(wù)器分別指出發(fā)信人和收信人的電子郵件地址。彼此自我介紹完畢之后,客戶發(fā)出郵件消息。SMTP可以指望由TCP提供的可靠數(shù)據(jù)傳輸服務(wù)把該消息無(wú)錯(cuò)地傳送到服務(wù)器。如果客戶還有其他郵件消息需發(fā)送到同一個(gè)服務(wù)器,它就在同一個(gè)TCP連接上重復(fù)上述過(guò)程;否則,它就指示TCP關(guān)閉該連接。
讓我們看一個(gè)客戶(C)和服務(wù)器(S)交互的例子??蛻羲谥鳈C(jī)名為crepes.fr,服務(wù)器所在主機(jī)名為hamburger.edu。前面標(biāo)以“C:”的ASCII文本行是客戶發(fā)送到它的TCP套接字中的完整文本行,前面標(biāo)以“S:”的ASCII文本行是服務(wù)器發(fā)送到它的TCP套接字中的完整文本行。以下傳輸腳本在TCP連接建立之后馬上發(fā)生:
S:220 hamburger.edu
C:HELO crepes.fr
S:250 Hello crepes.fr,pleased to meet you
C:MAIL FROM:
S:250 alice@crepes.fr ... Serder OK
C:RCPT TO:
S:250 bob@hamburger.edu...Recipient OK
C:DATA
S:354 Enter mail,end with "." on a line by its self
C:Do you like ketchup?
C:How about pickles?
C:.
S;250 Message accepted for delivery
C:QUIT
S:221 hamburger.edu cloing connection
在這個(gè)例子中,客戶發(fā)送了一個(gè)從郵件服務(wù)器主機(jī)crepes.fr到hamburger.edu的郵件消息,信體內(nèi)容為:“Do you like ketchup?How about pickles?”??蛻艨偣舶l(fā)出了5個(gè)命令,分別為:HELO,MAIL FROM,RCPT TO,DATA和QUIT。這些命令的含義是不言自明的。服務(wù)器給每個(gè)命令發(fā)回應(yīng)答,其中每個(gè)應(yīng)答都由應(yīng)答碼和一些英語(yǔ)解釋(可選)構(gòu)成。這里需指出的是,SMTP使用持久連接,也就是說(shuō),如果發(fā)送郵件服務(wù)器有多個(gè)郵件消息需發(fā)送到同一個(gè)接收郵件服務(wù)器,那么所有這些消息可以在同一個(gè)TCP連接中發(fā)送。對(duì)于其中的每一個(gè)消息,客戶以一個(gè)新的“HELO crepes.fr”命令開(kāi)始整個(gè)消息發(fā)送過(guò)程,但是QUIT命令要等到所有消息都發(fā)送完之后才發(fā)出。
我們可以嘗試使用nc工具直接與SMTP服務(wù)器進(jìn)行對(duì)話。首先指定使用SMTP端口號(hào)25連接到某臺(tái)郵件服務(wù)器主機(jī),這樣就在本地主機(jī)和該郵件服務(wù)器主機(jī)之間建立了一個(gè)SMTP使用的TCP連接。登錄完畢之后,應(yīng)該立即收到來(lái)服務(wù)器的應(yīng)答,接著就可以在合適的時(shí)刻依次發(fā)出現(xiàn)SMTP命令了。如果你連接到你朋友的5MTP服務(wù)器,就可以用這種方式向你的朋友發(fā)送郵件了(也就是說(shuō),不必使用郵件用戶代理)。當(dāng)然你也可以使用更常見(jiàn)的telnet工具,不過(guò)我發(fā)現(xiàn)用telnet建立起連接后常會(huì)遇到一些輸入方面的問(wèn)題。
與HTTP的比較
我們簡(jiǎn)單地比較一下SMTP和HTTP。這兩個(gè)協(xié)議都是用于從一臺(tái)主機(jī)向另一臺(tái)主機(jī)傳送文件;HTTP用于從web服務(wù)器向Web用戶代理(即瀏覽器)傳送文件(或?qū)ο?,SMTP用于從一個(gè)郵件服務(wù)器向另一個(gè)郵件服務(wù)器傳送文件(也就是電子郵件消息)。在傳送文件時(shí),SMTP和持久HTTP都使用持久連接??梢?jiàn),這兩個(gè)協(xié)議具有一些共同的特征,不過(guò)它們之間的差別也是顯著的。首先,HTTP基本上是一個(gè)內(nèi)拉式協(xié)議(pull protocol)——有人把信息上傳到web服務(wù)器中,用戶則在方便的時(shí)候使用HTTP把這些信息從服務(wù)器上拉過(guò)來(lái)。更確切地說(shuō),TCP連接是由想要接收文件的主機(jī)發(fā)起的。SMIP則基本上是一個(gè)外推式協(xié)議(pushProtoco1)——發(fā)送端郵件服務(wù)器把文件推送給接收端郵件服務(wù)器。更確切地說(shuō),TCP連接是由想要發(fā)送文件的主機(jī)發(fā)起的。
SMTP和HTTP的第二個(gè)重要差別是,SMTP要求包括信體部分在內(nèi)的每個(gè)郵件消息都是7位ASCII文本格式。
【編輯推薦】