1. 程式人生 > 實用技巧 >(轉)電子郵件收發原理和實現(POP3, SMTP)

(轉)電子郵件收發原理和實現(POP3, SMTP)

1.1.電子郵件的收發流程示意圖:

相對於郵件客戶端的流程就是:

1.2.郵件接收——POP3協議
POP3(Post Office Protocol 3,郵局協議版本3)主要用於支援使用客戶端遠端管理在伺服器上的電子郵件。該協議是在RFC-1939中定義的,是Internet上的大多數人用來接收郵件的機制。POP3採用Client/Server工作模式,預設使用TCP 110埠。

  • 在使用POP協議時,人們熟悉的很多功能,如檢視收到了多少新郵件訊息的功能,POP根本不支援。這些功能都內建到諸如Eudora或 Microsoft Outlook之類的郵件程式中,能為您記住接收的上一封郵件,以及計算有多少新郵件這類資訊。因此,如果想獲取這類資訊,將需要由自己進行計算。
    [詳細請參考wiki的解析:
    http://zh.wikipedia.org/wiki/POP3
    ]

<POP3狀態圖>

<POP3常用命令表>

命令可能的返回值

OK <描述> 成功
ERR <描述> 失敗
View Code

<POP3工作原理>
1) 客戶端使用TCP協議連線郵件伺服器的110埠;
2) 客戶端使用USER命令將郵箱的賬號傳給POP3伺服器;
3) 客戶端使用PASS命令將郵箱的賬號傳給POP3伺服器;
4) 完成使用者認證後,客戶端使用STAT命令請求伺服器返回郵箱的統計資料;
5) 客戶端使用LIST命令列出伺服器裡郵件數量;
6) 客戶端使用RETR命令接收郵件,接收一封后便使用DELE命令將郵件伺服器中的郵件置為刪除狀態;
7) 客戶端傳送QUIT命令,郵件伺服器將將置為刪除標誌的郵件刪除,連線結束。
(注:客戶端UA可以設定將郵件在郵件伺服器上保留備份,而不將其刪除。)

一個基本實現(C++):
暫無

1.3.郵件傳送——SMTP協議
SMTP(Simple Message Transfer Protocol,簡單郵件傳輸協議)是用於傳送電子郵件的機制。該協議是在RFC-821中定義的。採用Client/Server工作模式,預設使用TCP 25埠。
[詳細請參考wiki的解析:http://zh.wikipedia.org/wiki/SMTP]

<SMTP狀態圖>

<SMTP常用命令表>

命令可能的返回值

500 格式錯誤,命令不可識別(此錯誤也包括命令列過長)
501 引數格式錯誤
502 命令不可實現
503 錯誤的命令序列
504 命令引數不可實現
211 系統狀態或系統幫助響應
214 幫助資訊
220 <domain> 服務就緒
221 <domain> 服務關閉傳輸通道
421 <domain> 服務未就緒,關閉傳輸通道(當必須關閉時,此應答可以作為對任何命令的響應)
250 要求的郵件操作完成
251 使用者非本地,將轉發向<forward-path>
450 要求的郵件操作未完成,郵箱不可用(例如,郵箱忙)
550 要求的郵件操作未完成,郵箱不可用(例如,郵箱未找到,或不可訪問)
451 放棄要求的操作;處理過程中出錯
551 使用者非本地,請嘗試<forward-path>
452 系統儲存不足,要求的操作未執行
552 過量的儲存分配,要求的操作未執行
553 郵箱名不可用,要求的操作未執行(例如郵箱格式錯誤)
354 開始郵件輸入,以<CRLF>.<CRLF>結束
554 操作失敗
View Code

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協議將郵件傳送到傳送端郵件伺服器。

1.2.3. 郵件伺服器
郵件伺服器是電子郵件系統的核心,它用來發送和接收郵件。郵件伺服器不同於普通PC的是它幾乎是全天工作的,所以它可以在任何時候為使用者提供服務,後面將提到這正是為什麼需要郵件伺服器的一個重要原因。很多ISP都提供免費的郵件伺服器,如126提供smtp.126.com郵件伺服器。

郵件伺服器向其它郵件伺服器轉發郵件也是採用SMTP協議。


1.2.4. SMTP和郵件格式的關係
如前所述,SMTP是客戶機向伺服器傳送郵件時所使用的協議,其核心是2.2中所述的命令和響應,至於它命令和響應中所帶的引數採用什麼格式,則是依賴於其他標準的。例如DATA後所帶的引數,則應遵循郵件格式標準RFC822.

SMTP和郵件格式的關係可用這麼一個例子來說明。甲與乙書信往來,甲通過郵局向乙發信,郵局間轉交郵件可看成使用了SMTP協議,至於書信的格式則會因為地區習慣等的不同而不同(中國人的書信格式和美國人的書信格式不同),這個書信格式則可看成是郵件格式標準。

應當認識到不能孤立地看待協議,各個協議之間往往存在著耦合關係,但為了分析方便,我們在具體敘述某個協議時,只能抓住主要矛盾——主要闡述單個協議。

1.2.5. 瀏覽器傳送郵件用的什麼協議
瀏覽器如IE、Maxthon可通過登陸使用者郵箱,來收發郵件,這是怎樣實現的?例如[email protected]可通過登陸www.126.com來收發郵件。

這個過程是這樣的:[email protected]在www.126.com提供的郵件頁面上填寫的相應資訊(如發信人郵箱、收信人郵箱等),通過http協議被提交給126伺服器;126伺服器根據這些資訊組裝一封符合郵件規範的郵件(就像使用者代理一樣);然後smtp.126.com通過SMTP協議將這封郵件傳送到接收端郵件伺服器。

可以看出,瀏覽器傳送郵件只是使用者代理的功能直接放到郵件伺服器上去做了,至於郵件伺服器間傳送郵件還是採用的SMTP協議。我們看問題,如果有必要還是要適當地透過現象看本質。

1.3. 郵件的收發過程
一般情況下,一封郵件的傳送和接收過程如下。

1) 發信人在使用者代理裡編輯郵件,包括填寫發信人郵箱、收信人郵箱和郵件標題等等。

2) 使用者代理提取發信人編輯的資訊,生成一封符合郵件格式標準(RFC822)的郵件。

3) 使用者代理用SMTP將郵件傳送到傳送端郵件伺服器(即發信人郵箱所對應的郵件伺服器)。

4) 傳送端郵件伺服器用SMTP將郵件傳送到接收端郵件伺服器(即收信人郵箱所對應的郵件伺服器)。

5) 收信人呼叫使用者代理。使用者代理用POP3協議從接收端郵件伺服器取回郵件。

6) 使用者代理解析收到的郵件,以適當的形式呈現在收信人面前。

<SMTP工作原理>
SMTP,即簡單郵件傳送協議,所對應RFC文件為RFC821。同http等多數應用層協議一樣,它工作在C/S模式下,用來實現因特網上的郵件傳送。SMTP在整個電子郵件通訊中所處的位置如圖所示。

可以看出,SMTP是用來將客戶機上的郵件傳送到伺服器上。這裡的客戶機是指某次連線中的傳送方,伺服器是指相應的接收方。在講解發送郵件的整個通訊過程前,先解釋一下面幾個術語。


2.1. 通訊過程
一個具體的SMTP通訊(如傳送端郵件伺服器與接收端伺服器的通訊)的過程如下。

1) 傳送端郵件伺服器(以下簡稱客戶端)與接收端郵件伺服器(以下簡稱伺服器)的25號埠建立TCP連線。

2) 客戶端向伺服器傳送各種命令,來請求各種服務(如認證、指定傳送人和接收人)。

3) 伺服器解析使用者的命令,做出相應動作並返回給客戶端一個響應。

4) 2)和3)交替進行,直到所有郵件都發送完或兩者的連線被意外中斷。

從這個過程看出,命令和響應是SMTP協議的重點,下面將予以重點講述。

2.2. 命令和響應
2.2.1. 格式
SMTP的命令不多(14個),它的一般形式是:COMMAND [Parameter] <CRLF>。其中COMMAND是ASCII形式的命令名,Parameter是相應的命令引數,<CRLF>是回車換行符(0DH, 0AH)。

SMTP的響應也不復雜,它的一般形式是:XXX Readable Illustration。XXX是三位十進位制數;Readable Illustration是可讀的解釋說明,用來表明命令是否成功等。XXX具有如下的規律:以2開頭的表示成功,以4和5開頭的表示失敗,以3開頭的表示未完成(進行中)。

2.2.2. 一個例子
命令和響應的格式是語法,各命令和響應的意思則是語義,各命令和各響應在時間上的關係則是同步。下面將通過一個簡單的SMTP通訊過程來說明協議的這三個要素。

C:telnet smtp.126.com 25 / 以telnet方式連線126郵件伺服器 /

S:220 126.com Anti-spam GT for Coremail System (126com[071018]) / 220為響應數字,其後的為歡迎資訊,會應伺服器不同而不同/

C:HELO smtp.126.com / HELO 後用來填寫返回域名(具體含義請參閱RFC821),但該命令並不檢查後面的引數/

S:250 OK

C: MAIL FROM: bripengandre@126.com / 傳送者郵箱 /

S:250 … ./ “…”代表省略了一些可讀資訊 /

C:RCPT TO: [email protected] / 接收者郵箱 /

S:250 … ./ “…”代表省略了一些可讀資訊 /

C:DATA / 請求傳送資料 /

S:354 Enter mail, end with "." on a line by itself

C:Enjoy Protocol Studing

C:.

S:250 Message sent

C:QUIT / 退出連線 /

S:221 Bye
Example

分析上面的過程可參考註釋進行,這裡要補充如下幾點。

1) “C:”開頭的行(不包括"C:")是客戶端的輸入,而以“S:”開頭的行(不包括"S:")則是伺服器的輸出。

2) 上述的命令並不一定會一次性成功,伺服器會返回錯誤響應,客戶端應該按照協議規定的時序,來輸入後續的命令(或重複執行失敗的命令,或重置會話,或退出會話等等)。

2.2.3. 常用命令
SMTP命令不區分大小寫,但引數區分大小寫,有關這方面的詳細說明請參考RFC821。常用的命令如下。

HELO <domain> <CRLF>  向伺服器標識使用者身份傳送者能欺騙,說謊,但一般情況下伺服器都能檢測到。

MAIL FROM: <reverse-path> <CRLF>  <reverse-path>為傳送者地址,此命令用來初始化郵件傳輸,即用來對所有的狀態和緩衝區進行初始化。

RCPT TO:<forward-path> <CRLF>  <forward-path>用來標誌郵件接收者的地址,常用在MAIL FROM後,可以有多個RCPT TO。

DATA <CRLF>  將之後的資料作為資料傳送,以<CRLF>.<CRLF>標誌資料的結尾。

REST <CRLF>  重置會話,當前傳輸被取消。

NOOP <CRLF>  要求伺服器返回OK應答,一般用作測試。

QUIT <CRLF>  結束會話。

VRFY <string> <CRLF>  驗證指定的郵箱是否存在,由於安全方面的原因,伺服器大多禁止此命令。

EXPN <string> <CRLF>  驗證給定的郵箱列表是否存在,由於安全方面的原因,伺服器大多禁止此命令。

HELP <CRLF>  查詢伺服器支援什麼命令。
View Code

2.2.4. 常用響應
常用的響應如下所示,數字後的說明是從英文譯過來的。更詳細的說明請參考RFC821。

501 引數格式錯誤

502 命令不可實現

503 錯誤的命令序列

504 命令引數不可實現

211 系統狀態或系統幫助響應

214 幫助資訊

220<domain>服務就緒

221<domain>服務關閉

421<domain>服務未就緒,關閉傳輸通道

250 要求的郵件操作完成

251 使用者非本地,將轉發向<forward-path>

450 要求的郵件操作未完成,郵箱不可用

550 要求的郵件操作未完成,郵箱不可用

451 放棄要求的操作;處理過程中出錯

551 使用者非本地,請嘗試<forward-path>

452 系統儲存不足,要求的操作未執行

552 過量的儲存分配,要求的操作未執行

553 郵箱名不可用,要求的操作未執行

354 開始郵件輸入,以"."結束

554 操作失敗
View Code

轉自:https://blog.csdn.net/ly930156123/article/details/51657509
轉自:http://univasity.iteye.com/blog/1173296