郵件服務(wù)器基礎(chǔ):郵件服務(wù)相關(guān)協(xié)議三
MIME***類型中有一個(gè)相當(dāng)重要的名為MultiPart的類型需要專門討論。就像一個(gè)web頁面中可以包含多個(gè)對象(例如文本、圖像、JAVA小應(yīng)用程序等)那樣,一個(gè)電子郵件消息也可以包含多個(gè)對象。我們已經(jīng)知道,Web是通過各自獨(dú)立的HTTP響應(yīng)消息傳送每個(gè)對象的。因特網(wǎng)電子郵件則相反,它把同一個(gè)郵件消息的所有對象(即部分)封裝在單個(gè)消息中。具體地說,當(dāng)一個(gè)多媒體消息含有不止一個(gè)對象時(shí)(例如多個(gè)圖像或ASCII文本與圖像共存),其Content-Type:頭部的值通常為multipart/mixed。這頭部向接收用戶代理指出本消息中含有多個(gè)對象。既然多個(gè)對象共處同一個(gè)郵件消息,接收用戶代理就得有辦法確定:(1)每個(gè)對象的起止位置,(2)每個(gè)非ASCII文本對象的傳送編碼方式,(3)每個(gè)對象的內(nèi)容類型。這是通過在每個(gè)對象之間放置邊界字符串,并在每個(gè)對象之前定義Content-Type:和Content-Transfer-Encoding:頭部實(shí)現(xiàn)的。
為便于理解multipart/mixed,讓我們看一個(gè)例子。假設(shè)Alice想給BOb發(fā)送一個(gè)郵件消息,其內(nèi)容為一些ASCII文本,后跟一個(gè)JPEG圖像,再跟一些ASCII文本。Alice使用自己的用戶代理編輯文本并附上圖像后,該用戶代理生成一個(gè)大體如下的郵件消息;
From:alice@crepes.fr
To:bob@hamburger.edu
MIME-Version:1.0
Content-type:multipart/mixed;Boundary=StartOfNextPart
--StartOfNextPart
Dear bob,
Please look at the picture
--StartOfNextPart
Content-Transfer-Encoding:base64
Content-type:image/jpeg
(...base64編碼的數(shù)據(jù)...
...base64編碼的數(shù)據(jù)...)
--StartOfNextPart
there is some acsii letter here
從中我們可以看出,Content-type:頭部的Boundary參數(shù)用于指定分隔各個(gè)部分的邊界字符串。在郵件消息體中,該分隔字符串以兩個(gè)短劃線開頭,以CRLF結(jié)尾。
Received:頭部
我們已經(jīng)知道一個(gè)電子郵件消息由多個(gè)部件構(gòu)成。信體是郵件消息的核心,它是發(fā)送者發(fā)送給接收者的真正數(shù)據(jù)。對于多部分郵件消息來說,其信體本身由多個(gè)部分組成,而每個(gè)部分又有一個(gè)或多個(gè)說明其數(shù)據(jù)性質(zhì)的頭部。信體之前是一個(gè)空行和由多個(gè)郵件消息頭部組成的信頭。這些頭部既包括在RFC 822中定義的頭部,例如From:、To:和subject:也包括MIME頭部,例如Content-type:和Content-Transfer-Encoding:。除此之外,我們還得提及由SMTP接收服務(wù)器插到每個(gè)郵件消息的項(xiàng)端的Received:頭部,它給出了發(fā)出本消息的SMTP服務(wù)器的主機(jī)名(“from”)、收取本消息的SMTP服務(wù)器的主機(jī)名(“by”)以及接收服務(wù)器收取本消息的時(shí)間。因此,作為接收者的用戶看到的郵件消息大體如下:
Received:from crepes.fr by hamburger.edu;18 Oct 2005 05:53:37 GMT
From:alice@crepes.fr
To:bob@hamburger.edu
MIME-Version:1.0
Content-type:multipart/mixed;Boundary=StartOfNextPart
--StartOfNextPart
Dear bob,
Please look at the picture
--StartOfNextPart
Content-Transfer-Encoding:base64
Content-type:image/jpeg
(...base64編碼的數(shù)據(jù)...
...base64編碼的數(shù)據(jù)...)
--StartOfNextPart
there is some acsii letter here
有時(shí)候,單個(gè)郵件消息會有多個(gè)Received:頭部,有的還會有一個(gè)較復(fù)雜的Return-path:頭部。這是因?yàn)猷]件消息在從發(fā)送者的主機(jī)到接收者的主機(jī)的傳送過程中,可能會被轉(zhuǎn)發(fā)到不止一個(gè)SMTP服務(wù)器。例如,如果Bob指示他在主機(jī)hamburger.edu上的郵件服務(wù)器把他的所有郵件轉(zhuǎn)發(fā)到主機(jī)sushi.jp,那么他通過其用戶代理看到的郵件消息可能以大體如下的兩行開頭:
Received:from hamburger.edu by sushi.jp;18 Oct 2005 05:55:37 GMT
Received:from crepes.fr by hamburger.edu;18 Oct 2005 05:53:37 GMT
這些頭部給接收用戶代理提供了相應(yīng)郵件消息訪問過的SMTP服務(wù)器及訪問時(shí)間的蹤跡。SMTP規(guī)范所在的RPC 822詳細(xì)定義丁Received:頭部的語法。
郵件訪問協(xié)議
一旦SMTP把Alice發(fā)給Bob的郵件消息從Alice的郵件服務(wù)器傳送到Bob的郵件服務(wù)器,該郵件消息就存放在Bob的郵箱中。在此前的討論中,我們已假設(shè)Bob通過直接登錄到自己的郵件服務(wù)器主機(jī)啟動用戶代理來閱讀該郵件消息。直到20世紀(jì)90年代早期,這仍然是標(biāo)準(zhǔn)的做法。然而,當(dāng)今的用戶一般使用在本地PC機(jī)(或Mac機(jī))上執(zhí)行的用戶代理來閱讀郵件,而不管是辦公室PC機(jī)、家庭PC機(jī)還是便攜機(jī)。用戶在本地PC機(jī)上執(zhí)行用戶代理可享受諸多好處,包括方便查看多媒體郵件消息和附件。
郵件消息的接收者在本地PC機(jī)上執(zhí)行用戶代理時(shí),很自然的一個(gè)想法是在本地PC機(jī)上也運(yùn)行郵件服務(wù)器。然而這種方法存在一個(gè)問題。我們已經(jīng)知道,郵件服務(wù)器是管理郵箱并運(yùn)行SMlP的客戶端和服務(wù)器端的,這意味著如果收信人把自己的郵件服務(wù)器駐留在本地PC上,那么他不得不始終開著這臺PC機(jī)并連接在因特網(wǎng)上,以便接收可能在任意時(shí)刻到達(dá)的新郵件。對于大多數(shù)因特網(wǎng)用戶來說,這顯然是不現(xiàn)實(shí)或不經(jīng)濟(jì)的做法。相反,用戶一般只在本地PC機(jī)上運(yùn)行一個(gè)用戶代理,由它遠(yuǎn)程訪問存放在某臺共享的郵件服務(wù)器主機(jī)上的郵箱,而該郵件服務(wù)器主機(jī)總是連接在因特網(wǎng)上并為多個(gè)用戶所共享。該主機(jī)及其上的郵件服務(wù)器—般由該用戶的ISP(例如大學(xué)或公司)維護(hù)。
既然用戶代理運(yùn)行在各個(gè)用戶的本地PC機(jī)上,郵件服務(wù)器則運(yùn)行在ISP或機(jī)構(gòu)內(nèi)部網(wǎng)絡(luò)中的某臺服務(wù)器主機(jī)上,用戶代理和郵件服務(wù)器之間就得有一個(gè)彼此通信的協(xié)議。我們先查看一下出自從Alice的本地PC機(jī)的某個(gè)郵件消息如何設(shè)法到達(dá)Bob的SMTP郵件服務(wù)器。這個(gè)任務(wù)可簡單地由A11ce的用戶代理使用SMTP直接與Bob的郵件服務(wù)器進(jìn)行通信來完成。具體地說,從Alice的用戶代理發(fā)起建立一個(gè)到Bob的郵件服務(wù)器的TCP連接,并通過該連接發(fā)出SMTP握手命令,再用DATA命令上傳郵件消息,***關(guān)閉連接。這種方法盡管切實(shí)可行,卻很少被采用,因?yàn)樗鼪]有給Alice的用戶代理提供任何資源來應(yīng)對目標(biāo)郵件服務(wù)器臨時(shí)崩潰的情況。相反,通常采用的方法是先由Alice的用戶代理發(fā)起與自己的郵件服務(wù)器的一個(gè)SMTP會話,把郵件消息上傳到該郵件服務(wù)器;再由Alice的郵件服務(wù)器發(fā)起與Bob的郵件服務(wù)器的一次SMTP會話,把郵件消息中轉(zhuǎn)給Bob的郵件服務(wù)器。如果Bob的郵件服務(wù)器暫時(shí)不可用,Alice的郵件服務(wù)器就暫存該郵件消息,以后繼續(xù)嘗試。SMTP的RFC定義了可用于跨多個(gè)郵件服務(wù)器中轉(zhuǎn)郵件消息的SMTP命令。
現(xiàn)在的問題是,像Bob這樣在本地PC機(jī)上運(yùn)行用戶代理的收信人該如何獲取已到達(dá)自己的郵件服務(wù)器的郵件消息(該郵件服務(wù)器運(yùn)行在Bob的ISP中的某臺主機(jī)上)。通過引入用于從自己的郵件服務(wù)器到本地PC機(jī)上的用戶代理傳送郵件消息的郵件訪問協(xié)議,這個(gè)問題徹底得以解決。日前流行的郵件訪問協(xié)議有兩個(gè):郵局協(xié)議版本3(Post office ProtocolVersion 3,簡稱POP3)和因特網(wǎng)郵件訪問協(xié)議(Internet Mail Access Protocol,簡稱IMAP)。注意,用戶代理不可能使用SMTP從郵件服務(wù)器獲取郵件消息,因?yàn)猷]件消息的獲取是一個(gè)內(nèi)拉操作,而SMTP是一個(gè)外推協(xié)議。圖3匯總了因特網(wǎng)電子郵件系統(tǒng)個(gè)所用的協(xié)議:SMTP用于從發(fā)送者的郵件服務(wù)器到接收者的郵件服務(wù)器傳送郵件消息,也用于從發(fā)送者的用戶代理到發(fā)送者的郵件服務(wù)器傳送郵件消息;POP3或IMAP用于從接收者的郵件服務(wù)器到接收者的用戶代理傳送郵件消息。
圖3 電子郵件協(xié)議及它們的通信實(shí)體
【編輯推薦】