版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 摘 要</b></p><p> 在生活中、工作中,電子郵件都是必不可少的溝通交流工具,電子郵件(electronic mail,簡(jiǎn)稱(chēng)E-mail,標(biāo)志:@,也被大家昵稱(chēng)為“伊妹兒”),又稱(chēng)電子信箱、電子郵政,它是—種用電子手段提供信息交換的通信方式,是Internet應(yīng)用最廣的服務(wù),通過(guò)網(wǎng)絡(luò)的電子郵件系統(tǒng),用戶(hù)可以用非常低廉的價(jià)格(不管發(fā)送到哪里,都只需負(fù)擔(dān)
2、電話費(fèi)和網(wǎng)費(fèi)即可),以非??焖俚姆绞剑◣酌腌娭畠?nèi)可以發(fā)送到世界上任何你指定的目的地),與世界上任何一個(gè)角落的網(wǎng)絡(luò)用戶(hù)聯(lián)系,這些電子郵件可以是文字、圖像、聲音等各種方式。同時(shí),用戶(hù)可以得到大量免費(fèi)的新聞、專(zhuān)題郵件,并實(shí)現(xiàn)輕松的信息搜索。</p><p> 本論文主要對(duì)電子郵件其中一種協(xié)議——SMTP,進(jìn)行較為深入的研究與分析,介紹其基本概念,基本原理,以及基本的工作方式。在此基礎(chǔ)上,搭建本地SMTP服務(wù)器,并用網(wǎng)
3、絡(luò)比較流行的郵件客戶(hù)端,實(shí)現(xiàn)郵件的發(fā)送與轉(zhuǎn)發(fā)等簡(jiǎn)單功能。</p><p> 關(guān)鍵字:SMTP協(xié)議,電子郵件,客戶(hù)端</p><p><b> ABSTRACT</b></p><p> In life, work, email is an essential communication tool, e-mail (electronic m
4、ail, referred to as E-mail, mark: @, also nicknamed “Yemeir”), also known as E-mail, e-post, it is - kind of means electronic means of communication for the exchange of information, is the most widely used Internet servi
5、ce, network e-mail system, the user can use a very low price (regardless of where to send, are just a burdentelephone charges and net charge can), very fast (within a few seconds can be sent to any desti</p><p
6、> This thesis to conduct a more in-depth study on e-mail in one protocol - SMTP, introduce its basic concepts, basic principles, as well as basic work. Times based on setting up a local SMTP server, and network more
7、popular mail client, mail sent forwards simple function.</p><p> KeyWords: SMTP protocol, e-mail, client</p><p><b> 目 錄</b></p><p><b> 第1章引言1</b></p&
8、gt;<p> 1.1選題背景1</p><p> 1.2研究目標(biāo)和意義1</p><p> 第2章SMTP協(xié)議概述2</p><p> 2.1協(xié)議簡(jiǎn)介2</p><p> 2.2協(xié)議原理3</p><p> 2.2.1SMTP命令3</p><p&
9、gt; 2.2.2信封、首部和正文4</p><p> 2.2.3工作模型4</p><p> 2.2.4工作過(guò)程6</p><p> 第3章相關(guān)協(xié)議介紹10</p><p> 3.1POP3協(xié)議10</p><p> 3.2IMAP4協(xié)議11</p><p>
10、; 第4章SMTP協(xié)議客戶(hù)端軟件設(shè)計(jì)與實(shí)現(xiàn)12</p><p> 4.1需求分析與總體設(shè)計(jì)12</p><p> 4.1.1功能分析12</p><p> 4.1.2總體設(shè)計(jì)12</p><p> 4.2各模塊設(shè)計(jì)14</p><p> 4.2.1實(shí)現(xiàn)SMTP協(xié)議的核心類(lèi)庫(kù)14<
11、;/p><p> 4.2.2模塊之間的關(guān)系19</p><p> 4.3核心模塊實(shí)現(xiàn)與核心功能編碼20</p><p> 4.3.1郵件發(fā)送實(shí)現(xiàn)20</p><p> 4.3.2郵件內(nèi)容相關(guān)實(shí)現(xiàn)24</p><p> 4.3.3郵件的編碼方式27</p><p> 第
12、5章軟件測(cè)試30</p><p><b> 參考文獻(xiàn)34</b></p><p><b> 致謝35</b></p><p><b> 外文資料原文36</b></p><p><b> 譯文47</b></p><
13、p><b> 引言</b></p><p><b> 選題背景</b></p><p> 隨著信息技術(shù)的發(fā)展、互聯(lián)網(wǎng)的普及,電子郵件已經(jīng)逐漸成為人們正常工作和生活中進(jìn)行溝通的重要手段。采用電子郵件服務(wù)可以方便快捷的與朋友、同事或合作伙伴進(jìn)行溝通,傳遞信息。電子郵件技術(shù)具有方便、快捷、成本低廉等特性。能夠大大減少信息傳遞的時(shí)間,比傳統(tǒng)的
14、信件傳遞方式更快捷,成本也更低。在實(shí)現(xiàn)過(guò)程中加入了認(rèn)證機(jī)制,因而,更安全、可靠。</p><p> 電子郵件(e-mail)無(wú)疑是最流行的應(yīng)用程序。[Caceres et al.1991]說(shuō)明,所有TCP連接中大約一半是用于簡(jiǎn)單郵件傳送協(xié)議SMTP(Simple Mail Transfer Protocol)的(以比特計(jì)算為基礎(chǔ),F(xiàn)TP連接傳送更多的數(shù)據(jù))。[Paxson 1993]發(fā)現(xiàn),平均每個(gè)郵件中包含大約
15、1500字節(jié)的數(shù)據(jù),但有的郵件中包含兆比特的數(shù)據(jù),因?yàn)橛袝r(shí)電子郵件也用于發(fā)送文件。</p><p><b> 研究目標(biāo)和意義</b></p><p> 目前與郵件相關(guān)的協(xié)議大概可以分為兩種:一種是郵件發(fā)送協(xié)議――SMTP協(xié)議;另一種是郵件接收協(xié)議――POP協(xié)議。本論文討論的是用于發(fā)送郵件的SMTP協(xié)議。目前,SMTP協(xié)議已經(jīng)有了大量的實(shí)現(xiàn),應(yīng)用廣泛。本軟件是為了研
16、究SMTP協(xié)議而作的一個(gè)實(shí)驗(yàn)型項(xiàng)目。目的在于掌握SMTP的工作原理,并實(shí)現(xiàn)一個(gè)能夠發(fā)送郵件的完整郵件客戶(hù)端。最后的成果和目標(biāo)是實(shí)現(xiàn)SMTP協(xié)議及其基本命令,進(jìn)行郵件發(fā)送及轉(zhuǎn)發(fā)。</p><p><b> SMTP協(xié)議概述</b></p><p><b> 協(xié)議簡(jiǎn)介</b></p><p> SMTP(Simple M
17、ail Transfer Protocol)即簡(jiǎn)單郵件傳輸協(xié)議,它是一組用于由源地址到目的地址傳送郵件的規(guī)則,由它來(lái)控制信件的中轉(zhuǎn)方式。SMTP協(xié)議屬于TCP/IP協(xié)議族,它幫助每臺(tái)計(jì)算機(jī)在發(fā)送或中轉(zhuǎn)信件時(shí)找到下一個(gè)目的地。通過(guò)SMTP協(xié)議所指定的服務(wù)器,就可以把E-mail寄到收信人的服務(wù)器上了,整個(gè)過(guò)程只要幾分鐘。SMTP服務(wù)器則是遵循SMTP協(xié)議的發(fā)送郵件服務(wù)器,用來(lái)發(fā)送或中轉(zhuǎn)發(fā)出的電子郵件。</p><p&g
18、t; SMTP是一種TCP協(xié)議支持的提供可靠且有效電子郵件傳輸?shù)膽?yīng)用層協(xié)議。SMTP 是建立在TCP上的一種郵件服務(wù),主要用于傳輸系統(tǒng)之間的郵件信息并提供來(lái)信有關(guān)的通知。</p><p> SMTP獨(dú)立于特定的傳輸子系統(tǒng),且只需要可靠有序的數(shù)據(jù)流信道支持。SMTP 重要特性之一是其能跨越網(wǎng)絡(luò)傳輸郵件,即“ SMTP 郵件中繼”。通常,一個(gè)網(wǎng)絡(luò)可以由公用互聯(lián)網(wǎng)上 TCP 可相互訪問(wèn)的主機(jī)、防火墻分隔的 TCP/
19、IP 網(wǎng)絡(luò)上 TCP 可相互訪問(wèn)的主機(jī),及其它 LAN/WAN 中的主機(jī)利用非 TCP 傳輸層協(xié)議組成。使用 SMTP ,可實(shí)現(xiàn)相同網(wǎng)絡(luò)上處理機(jī)之間的郵件傳輸,也可通過(guò)中繼器或網(wǎng)關(guān)實(shí)現(xiàn)某處理機(jī)與其它網(wǎng)絡(luò)之間的郵件傳輸。</p><p> 在這種方式下,郵件的發(fā)送可能經(jīng)過(guò)從發(fā)送端到接收端路徑上的大量中間中繼器或網(wǎng)關(guān)主機(jī)。域名服務(wù)系統(tǒng)(DNS)的郵件交換服務(wù)器可以用來(lái)識(shí)別出傳輸郵件的下一條 IP 地址。</p
20、><p> 在傳輸文件過(guò)程中使用端口:25</p><p> 是因特網(wǎng)電子郵件系統(tǒng)首要的應(yīng)用 層協(xié)議。它使用由TCP提供的可靠的數(shù)據(jù)傳輸服務(wù)把郵件消息從發(fā)信人的郵件服務(wù)器傳送到收信人的郵件服務(wù)器。跟大多數(shù)應(yīng)用層協(xié)議一樣,SMTP也存在兩個(gè) 端:在發(fā)信人的郵件服務(wù)器上執(zhí)行的客戶(hù)端和在收信人的郵件服務(wù)器上執(zhí)行的服務(wù)器端。SMTP的客戶(hù)端和服務(wù)器端同時(shí)運(yùn)行在每個(gè)郵件服務(wù)器上。當(dāng)一個(gè)郵件服 務(wù)器在
21、向其他郵件服務(wù)器發(fā)送郵件消息時(shí),它是作為SMTP客戶(hù)在運(yùn)行。當(dāng)一個(gè)郵件服務(wù)器從其他郵件服務(wù)器接收郵件消息時(shí),它是作為SMTP服務(wù)器在運(yùn)行。</p><p> SMTP協(xié)議與人們用于面對(duì)面交互的禮儀之間有許多相似之處。首先,運(yùn)行在發(fā)送端郵件服務(wù)器主機(jī)上的SMTP客戶(hù),發(fā)起建立一個(gè)到運(yùn)行在接收端郵件服務(wù) 器主機(jī)上的SMTP服務(wù)器端口號(hào)25之間的TCP連接。如果接收郵件服務(wù)器當(dāng)前不在工作,SMTP客戶(hù)就等待一段時(shí)間后
22、再?lài)L試建立該連接。這個(gè)連接建立之 后,SMTP客戶(hù)和服務(wù)器先執(zhí)行一些應(yīng)用層握手操作。就像人們?cè)谵D(zhuǎn)手東西之前往往先自我介紹那樣,SMTP客戶(hù)和服務(wù)器也在傳送信息之前先自我介紹一下。 在這個(gè)SMTP握手階段,SMTP客戶(hù)向服務(wù)器分別指出發(fā)信人和收信人的電子郵件地址。彼此自我介紹完畢之后,客戶(hù)發(fā)出郵件消息。SMTP可以指望由 TCP提供的可靠數(shù)據(jù)傳輸服務(wù)把該消息無(wú)錯(cuò)地傳送到服務(wù)器。如果客戶(hù)還有其他郵件消息需發(fā)送到同一個(gè)服務(wù)器,它就在同一個(gè)TC
23、P連接上重復(fù)上述過(guò)程;否 則,它就指示TCP關(guān)閉該連接。</p><p><b> 協(xié)議原理</b></p><p> 從1982年到現(xiàn)在,SMTP協(xié)議及其相關(guān)的協(xié)議已經(jīng)發(fā)展成一個(gè)比較完整的體系,不再是建立之初那個(gè)只能傳送文本消息的簡(jiǎn)單協(xié)議。協(xié)議制定者制定了一系列的相關(guān)協(xié)議,如:有關(guān)認(rèn)證的部分和附件傳送部分等。相關(guān)文檔也由最初的RFC821文檔,擴(kuò)展為目前的RFC
24、2821、RFC2045-2049、RFC2554等多個(gè)。目前按照郵件協(xié)議的規(guī)定已經(jīng)不僅僅能夠傳送文本,而且能夠傳送文件,網(wǎng)頁(yè)以及多媒體信息。但基本的操作模式?jīng)]有變化,只是增加了相關(guān)的命令和格式。郵件傳送的模型,沒(méi)有變化。</p><p><b> SMTP命令</b></p><p> 最小SMTP實(shí)現(xiàn)支持8種命令。常見(jiàn)的有5個(gè):HELO,MAIL,RCPT,D
25、ATA和QUIT。</p><p> RSET命令異常終止當(dāng)前的郵件事物并使兩端復(fù)位。丟掉所有有關(guān)發(fā)送方、接收方或郵件的存儲(chǔ)信息。</p><p> VRFY命令使客戶(hù)能夠詢(xún)問(wèn)發(fā)送方以驗(yàn)證接受方地址,而無(wú)需向接收方發(fā)送郵件。通常是系統(tǒng)管理員在查找郵件交付差錯(cuò)時(shí)手工使用的。</p><p> NOOP命令除了強(qiáng)迫服務(wù)器響應(yīng)一個(gè)OK應(yīng)答碼(200)外,不做任何事情
26、</p><p> 還有附加和可選命令。EXPN擴(kuò)充郵件表,與VRFY類(lèi)似,通常是由系統(tǒng)管理員使用的。</p><p> TURN命令使客戶(hù)和服務(wù)器交換角色,無(wú)需拆除TCP連接并建立新的連接就能以相反方向發(fā)送郵件。其他還有三個(gè)很少被實(shí)現(xiàn)的命令(SEND、SOML和SAML)取代MAIL命令。這三個(gè)命令允許郵件直接發(fā)送到客戶(hù)終端或發(fā)送到接受方的郵箱。</p><p&g
27、t;<b> 信封、首部和正文</b></p><p> 電子郵件由三部分組成:</p><p> 1)信封(envelope)是MTA用來(lái)交付的。RFC 821指明了信封的內(nèi)容及其解釋?zhuān)约霸谝粋€(gè)TCP連接上用于交換郵件的協(xié)議。</p><p> 2)首部由用戶(hù)代理使用。RFC 822指明了首部字段的格式的解釋?zhuān)ㄒ訶-開(kāi)始的首部字段是
28、用戶(hù)定義的字段,其他是由RFC 822定義的)。長(zhǎng)首部字段,多余行以空格開(kāi)頭。</p><p> 3)正文(body)是發(fā)送用戶(hù)發(fā)給接收用戶(hù)報(bào)文的內(nèi)容。RFC 822指定正文為NVT ASCII文字行。當(dāng)用DATA命令發(fā)送時(shí),先發(fā)送首部,緊跟一個(gè)空行,然后是正文。用DATA命令發(fā)送的各行都必須小于1000字節(jié)。</p><p> 用戶(hù)接收我們指定為正文的部分,加上一些首部字段,并把結(jié)果
29、傳到MTA。MTA加上一些首部字段,加上信封,并把結(jié)果發(fā)送到另一個(gè)MTA。</p><p> 內(nèi)容(content)通常用于描述首部和正文的結(jié)合。內(nèi)容是客戶(hù)用DATA命令發(fā)送的。</p><p><b> 工作模型</b></p><p> SMTP設(shè)計(jì)基于以下通信模型:針對(duì)用戶(hù)的郵件請(qǐng)求,發(fā)送SMTP建立與接收SMTP之間建立一個(gè)雙向的
30、傳送通道,用于發(fā)送與接收SMTP的命令與應(yīng)答碼。其中接收SMTP可以是最終接受者也可以是中間傳送者。SMTP命令由發(fā)送SMTP發(fā)出,由接收SMTP接收,而應(yīng)答則反方向傳送。</p><p> 一旦傳送通道建立,SMTP發(fā)送者發(fā)送MAIL命令指明郵件發(fā)送者。如果SMTP接受者可以接收郵件則返回OK應(yīng)答。SMTP發(fā)送者再發(fā)出RCPT命令指明郵件接收者。如果SMTP接收者能夠接收,那么返回OK作為應(yīng)答;如果不能收到,
31、則返回拒絕應(yīng)答(但并不中止整個(gè)郵件操作),雙發(fā)如此重復(fù)多次。當(dāng)接收者收到全部郵件后就會(huì)收到特別的序列,如果接受者成功處理了郵件,則返回OK應(yīng)答。如圖2-1所示。</p><p> 圖2-1 SMTP工作模型</p><p> SMTP提供傳送郵件的機(jī)制,如果接收方與發(fā)送方連接在同一個(gè)傳送服務(wù)器時(shí),郵件可以直接由發(fā)送方主機(jī)傳送到接收方主機(jī);或者,當(dāng)兩者不在同一個(gè)傳送服務(wù)器時(shí),通過(guò)中繼SM
32、TP服務(wù)器傳送。為了能夠?qū)MTP服務(wù)器提供中繼能力,它必須擁有最終目的主機(jī)地址和郵箱名稱(chēng)。</p><p> MAIL命令參數(shù)是回復(fù)路徑,它指定郵件從何處來(lái);而RCPT命令的參數(shù)是轉(zhuǎn)發(fā)路徑的,它指定郵件向何處去。向前路徑是源路徑,而回復(fù)路徑是返回路徑(它用于發(fā)生錯(cuò)誤時(shí)返回郵件)。</p><p> 當(dāng)同一個(gè)消息要發(fā)往不同的接收者時(shí),SMTP遇到了向不同接收者發(fā)送同一份數(shù)據(jù)的復(fù)制品的問(wèn)
33、題,郵件命令和應(yīng)答有一個(gè)比較奇怪的語(yǔ)法,應(yīng)答也有一個(gè)數(shù)字代碼。</p><p> 命令與應(yīng)答對(duì)大小寫(xiě)不敏感,也就是說(shuō),命令和應(yīng)答可以是大寫(xiě),小寫(xiě)或兩者的混合,但這一點(diǎn)對(duì)用戶(hù)郵件名稱(chēng)卻不一定是對(duì)的,因?yàn)橛械闹鳈C(jī)對(duì)用戶(hù)名大小寫(xiě)是敏感的。這樣SMTP實(shí)現(xiàn)中就將用戶(hù)郵箱名稱(chēng)保留成初始時(shí)的樣子,主機(jī)名稱(chēng)對(duì)大小寫(xiě)不敏感。</p><p> 命令與應(yīng)答由ASCII字母表組成,當(dāng)傳送服務(wù)提供8位字節(jié)傳
34、送通道,每7位字符正確傳送,而最高位被填充為0。當(dāng)指定一般的命令或應(yīng)答格式后,參數(shù)會(huì)由一些類(lèi)似于語(yǔ)言的字符串表示出來(lái),如"<string>"或"<reverse-path>",這里尖括號(hào)表示這是一種類(lèi)似于語(yǔ)言的變量。</p><p><b> 工作過(guò)程</b></p><p> 從SMTP協(xié)議的整體工
35、作過(guò)程來(lái)看,客戶(hù)端和服務(wù)器是典型的C/S結(jié)構(gòu),由客戶(hù)端向服務(wù)器發(fā)起連接請(qǐng)求,發(fā)送相關(guān)的命令(也可以說(shuō)是要求的服務(wù)),等待服務(wù)器的相關(guān)信息。得到服務(wù)器的信息后,對(duì)這些信息進(jìn)行分析,再繼續(xù)進(jìn)行下一步操作。本節(jié)中提供了一些相關(guān)過(guò)程舉例和命令的說(shuō)明,具體描述了SMTP協(xié)議中數(shù)據(jù)的交互過(guò)程。本節(jié)只介紹了少數(shù)幾個(gè)SMTP命令和代碼,本節(jié)末尾有詳細(xì)的命令列表和代碼列表。</p><p><b> 1、傳送</
36、b></p><p> 在SMTP發(fā)送操作中有三步,操作由MAIL命令開(kāi)始給出發(fā)送者標(biāo)識(shí)。一系列或更多的RCPT命令緊跟其后,給出了接收者信息,然后是DATA命令列出發(fā)送的郵件內(nèi)容,最后郵件內(nèi)容指示符確認(rèn)操作。</p><p> 1)過(guò)程中的第一步是MAIL命令,<reverse-path>包括源郵箱。</p><p> MAIL<S
37、P>FROM:<reverse-path><CRLF></p><p> 此命令告訴接收者新的發(fā)送操作已經(jīng)開(kāi)始,請(qǐng)復(fù)位所有狀態(tài)表和緩沖區(qū)。它給出反向路徑以進(jìn)行錯(cuò)誤信息返回。如果請(qǐng)求被接收,接收方返回一個(gè)250 OK應(yīng)答。<reverse-path>中不止包括了郵箱,它包括了主機(jī)和源郵箱的反向路由,其中的第一個(gè)主機(jī)就是發(fā)送此命令的主機(jī)。</p><p&
38、gt; 2)過(guò)程中的第二步是發(fā)送RCPT命令。</p><p> RCPT<SP> TO: <forward-path><CRLF></p><p> 此命令給出向前路徑標(biāo)識(shí)接收者,如果命令被接收,接收方返回一個(gè)250 OK應(yīng)答,并存儲(chǔ)向前路徑。如果接收者未知,接收方會(huì)返回一個(gè)550 Failure應(yīng)答。此過(guò)程可能會(huì)重復(fù)若干次。</p>
39、;<p> <forward-path>不僅包括郵件,它是主機(jī)和目的郵箱的路由表,在其中的第一個(gè)主機(jī)就是接收命令的主機(jī)。</p><p> 3)過(guò)程中的第三步是發(fā)送DATA命令。DATA<CRLF></p><p> 如果命令被接收,接收方返回一個(gè)354 Intermediate應(yīng)答,并認(rèn)定以下的各行都是信件內(nèi)容。當(dāng)信件結(jié)尾收到并存儲(chǔ)后,接收者
40、發(fā)送一個(gè) 250 OK應(yīng)答。因?yàn)猷]件是在傳送通道上發(fā)送,因此必須指明郵件內(nèi)容結(jié)尾,以便應(yīng)答對(duì)話可以重新開(kāi)始。SMTP通過(guò)在最后一行僅發(fā)送一個(gè)句號(hào)來(lái)表示郵件 內(nèi)容的結(jié)束,在接收方,一個(gè)對(duì)用戶(hù)透明的過(guò)程將此符號(hào)過(guò)濾掉,以不影響正常的數(shù)據(jù)。</p><p> 注意:郵件內(nèi)容包括如下提示:Date,Subject,From,To。</p><p> 郵件內(nèi)容指示符確認(rèn)郵件操作并告知接收者可以存
41、儲(chǔ)和再發(fā)送數(shù)據(jù)了。如果此命令被接收,接收方返回一個(gè)250 OK應(yīng)答。DATA命令僅在郵件操作未完成或源無(wú)效的情況下失敗。</p><p> 上面所述的過(guò)程是一個(gè)發(fā)送操作。這些命令只能以上面的順序使用。下例表示了在一個(gè)發(fā)送操作中這些命令的使用。</p><p> SMTP過(guò)程例子此例是在qq.com主機(jī)的123發(fā)送郵件給qq.com主機(jī)的234,345和456的。</p>
42、<p> S:MAIL FROM:123@qq.com</p><p><b> R: 250 OK</b></p><p> S: RCPT TO:<234@qq.com></p><p><b> R: 250 OK</b></p><p> S: RCPT TO
43、:<345@qq.com></p><p> R: 550 No such user here</p><p> S: RCPT TO:456@qq.com </p><p><b> R: 250 OK</b></p><p><b> S: DATA</b></p>
44、;<p> R: 354 Start mail input; end with <CRLF>.<CRLF></p><p> S: Blah blah blah...</p><p><b> S:..等等</b></p><p> S: <CRLF>.<CRLF></p><p><b>
45、; R: 250 OK</b></p><p> 此信被第一和三兩個(gè)人接收,而第二個(gè)人在此主機(jī)上沒(méi)有郵箱。</p><p><b> 2、打開(kāi)與退出</b></p><p> 想進(jìn)行郵件的發(fā)送,就要有一對(duì)用于傳送信息的通道。這條通道就是發(fā)送者和接接收者用戶(hù)發(fā)送和接收數(shù)據(jù)的保證。在SMTP中規(guī)定了建立和銷(xiāo)毀通道的命令。建立命令
46、為:HELO(EHLO)。銷(xiāo)毀的命令為:QUIT。這兩個(gè)命令的正確應(yīng)答碼為220和221。信道正常被建立或銷(xiāo)毀的時(shí)候,服務(wù)器端和客戶(hù)端會(huì)分別依靠命令和應(yīng)答碼來(lái)打開(kāi)或關(guān)閉信道。</p><p> 打開(kāi)傳送通道時(shí),要交換一些信息以確定雙方的身份。以下的命令是用于打開(kāi)和關(guān)閉的:</p><p> HELO <SP> <domain> <CRLF></p><p>
47、QUIT <CRLF></p><p> 在HELLO命令中,主機(jī)自己發(fā)送命令,此命令可以被解釋為:“你好,我是XX”</p><p><b> 打開(kāi)連接的例子:</b></p><p> R: 220 qq.com Simple Mail Transfer Service Ready</p><p>
48、S: HELO xx</p><p> R: 250 qq.com</p><p><b> 關(guān)閉聯(lián)結(jié)的例子</b></p><p><b> S: QUIT</b></p><p> R: 221 BBN-UNIX.ARPA Service closing transmission
49、 channel</p><p> 從整個(gè)SMTP協(xié)議的工作過(guò)程來(lái)看,整個(gè)過(guò)程很類(lèi)似于一對(duì)朋友的談話,首先要由客戶(hù)端的朋友先向服務(wù)器端開(kāi)口說(shuō)HELO,然后服務(wù)器端回答它的話。接下來(lái)客戶(hù)端就會(huì)根據(jù)一定的順序,來(lái)繼續(xù)的和服務(wù)器朋友進(jìn)行交流,直到雙方談話結(jié)束,客戶(hù)端會(huì)主動(dòng)的說(shuō)QUIT,表示自己要走了。服務(wù)器會(huì)回復(fù)它一個(gè)正常的代碼。之后雙方的交流就正式的結(jié)束了。應(yīng)答碼列表如圖2-2所示。</p><
50、;p> 圖2-2 SMTP協(xié)議應(yīng)答碼</p><p><b> 相關(guān)協(xié)議介紹</b></p><p><b> POP3協(xié)議</b></p><p> POP3(Post Office Protocol 3)即郵局協(xié)議的第3個(gè)版本,它是規(guī)定個(gè)人計(jì)算機(jī)如何連接到互聯(lián)網(wǎng)上的郵件服務(wù)器進(jìn)行收發(fā)郵件的協(xié)議。它是因特網(wǎng)
51、電子郵件的第一個(gè)離線協(xié)議標(biāo)準(zhǔn),POP3協(xié)議允許用戶(hù)從服務(wù)器上把郵件存儲(chǔ)到本地主機(jī)(即自己的計(jì)算機(jī))上,同時(shí)根據(jù)客戶(hù)端的操作刪除或保存在郵件服務(wù)器上的郵件,而POP3服務(wù)器則是遵循POP3協(xié)議的接收郵件服務(wù)器,用來(lái)接收電子郵件的。POP3協(xié)議是TCP/IP協(xié)議族中的一員,,由RFC 1939 定義。本協(xié)議主要用于支持使用客戶(hù)端遠(yuǎn)程管理在服務(wù)器上的電子郵件</p><p> POP3,全名為“Post Office
52、 Protocol - Version 3”,即“郵局協(xié)議版本3”。是TCP/IP協(xié)議族中的一員,由RFC1939 定義。本協(xié)議主要用于支持使用客戶(hù)端遠(yuǎn)程管理在服務(wù)器上的電子郵件。提供了SSL加密的POP3協(xié)議被稱(chēng)為POP3S。</p><p> POP 協(xié)議支持“離線”郵件處理。其具體過(guò)程是:郵件發(fā)送到服務(wù)器上,電子郵件客戶(hù)端調(diào)用郵件客戶(hù)機(jī)程序以連接服務(wù)器,并下載所有未閱讀的電子郵件。這種離線訪問(wèn)模式是一種存
53、儲(chǔ)轉(zhuǎn)發(fā)服務(wù),將郵件從郵件服務(wù)器端送到個(gè)人終端機(jī)器上,一般是 PC機(jī)或 MAC。一旦郵件發(fā)送到 PC 機(jī)或 MAC上,郵件服務(wù)器上的郵件將會(huì)被刪除。但目前的POP3郵件服務(wù)器大都可以“只下載郵件,服務(wù)器端并不刪除”,也就是改進(jìn)的POP3協(xié)議。</p><p> POP3協(xié)議默認(rèn)端口:110</p><p> POP3協(xié)議默認(rèn)傳輸協(xié)議:TCP</p><p> P
54、OP3協(xié)議適用的構(gòu)架結(jié)構(gòu):C/S</p><p> POP3協(xié)議的訪問(wèn)模式:離線訪問(wèn)</p><p><b> IMAP4協(xié)議</b></p><p> IMAP4(Internet Message Access Protocol 4) 即 交互式數(shù)據(jù)消息訪問(wèn)協(xié)議第四個(gè)版本。IMAP協(xié)議是由斯坦福大學(xué)的Mark Crispin教授在198
55、6年開(kāi)發(fā)的,后期版本是華盛頓州立大學(xué)進(jìn)行開(kāi)發(fā)的,IMAP4是TCP/IP協(xié)議族中的一員,現(xiàn)在的版本是“IMAP第四版第一次修訂版”(IMAP4rev1)。</p><p> IMAP4協(xié)議與POP3協(xié)議一樣也是規(guī)定個(gè)人計(jì)算機(jī)如何訪問(wèn)互聯(lián)網(wǎng)上的郵件服務(wù)器進(jìn)行收發(fā)郵件的協(xié)議,但是IMAP4協(xié)議同POP3協(xié)議相比更高級(jí)。IMAP4協(xié)議支持客戶(hù)機(jī)在線或者離線訪問(wèn)并閱讀服務(wù)器上的郵件,還能交互式的操作服務(wù)器上的郵件。IM
56、AP4協(xié)議更人性化的地方是不需要像POP3協(xié)議那樣把郵件下載到本地,用戶(hù)可以通過(guò)客戶(hù)端直接對(duì)服務(wù)器上的郵件進(jìn)行操作(這里的操作是指:在線閱讀郵件 在線查看郵件主題 大小 發(fā)件地址等信息)。用戶(hù)還可以在服務(wù)器上維護(hù)自己郵件目錄(維護(hù)是指移動(dòng) 新建 刪除 重命名 共享 抓取文本 等操作)。IMAP4協(xié)議彌補(bǔ)了POP3協(xié)議的很多缺陷,,由RFC3501定義。本協(xié)議是用于客戶(hù)機(jī)遠(yuǎn)程訪問(wèn)服務(wù)器上電子郵件,它是郵件傳輸協(xié)議新的標(biāo)準(zhǔn)。</p&g
57、t;<p> IMAP4協(xié)議的默認(rèn)端口:143</p><p> IMAP4協(xié)議默認(rèn)傳輸協(xié)議:TCP/IP</p><p> IMAP4協(xié)議適用的網(wǎng)絡(luò)構(gòu)架:C/S</p><p> IMAP4協(xié)議訪問(wèn)模式:離線/在線</p><p> IMAP4協(xié)議存儲(chǔ)郵件模式:分布式</p><p> SM
58、TP協(xié)議客戶(hù)端軟件設(shè)計(jì)與實(shí)現(xiàn)</p><p><b> 需求分析與總體設(shè)計(jì)</b></p><p><b> 功能分析</b></p><p> 由本設(shè)計(jì)的題目可知,本設(shè)計(jì)的目的就是建立一款能夠發(fā)送郵件的客戶(hù)端軟件。對(duì)本軟件而言,應(yīng)該具備如下功能:</p><p> 1)可以根據(jù)用戶(hù)輸入的數(shù)
59、據(jù)連接服務(wù)器。</p><p> 3)可以對(duì)有關(guān)數(shù)據(jù)進(jìn)行加密。</p><p> 4)可以發(fā)送郵件信息。</p><p> 5)圖形界面要信息完整、操作舒適、界面雅觀。</p><p> 根據(jù)以上分析,需要進(jìn)行編碼的操作有:</p><p> 1)從圖形界面獲取輸入的數(shù)據(jù)的操作。</p>&l
60、t;p> 2)根據(jù)MFC提供的API連接服務(wù)器,建立一條連接發(fā)送者和接收者的通道。</p><p> 3)提供BASE64的加密算法,能夠?qū)τ脩?hù)輸入的數(shù)據(jù)進(jìn)行加密。生成滿足SMTP協(xié)議要求的數(shù)據(jù)。</p><p> 4)按照SMTP的要求,對(duì)郵件進(jìn)行封裝,生成滿足協(xié)議要求的郵件。</p><p> 5)對(duì)郵件發(fā)送過(guò)程中,發(fā)送者與接收者之間的命令
61、與應(yīng)答碼之間的關(guān)系進(jìn)行分析。</p><p> 6) 圖形界面編程。</p><p><b> 總體設(shè)計(jì)</b></p><p> 目前流行的工作平臺(tái)有很多,可以實(shí)現(xiàn)目標(biāo)的編程語(yǔ)言也有多種。下面與流行的兩種平臺(tái)做比較并說(shuō)明選擇VC++的原因:</p><p> 1、整個(gè)工程使用JAVA平臺(tái)</p>
62、<p> 從誕生至今,一路走來(lái)JAVA可以說(shuō)是一帆風(fēng)順。已經(jīng)超越了C++稱(chēng)為最受歡迎的語(yǔ)言之一。如果選擇使用JAVA作為開(kāi)發(fā)語(yǔ)言,并使用一種集成IDE,如:JBUILDER。調(diào)用下JAVA有關(guān)郵件發(fā)送的類(lèi)庫(kù),那么整個(gè)的郵件發(fā)送過(guò)程就變成了對(duì)少數(shù)幾個(gè)屬性的設(shè)定問(wèn)題,整個(gè)工程的主要任務(wù)就不再是對(duì)SMTP協(xié)議的分析,而僅僅是對(duì)有關(guān)界面的設(shè)計(jì)(而且JAVA的界面設(shè)計(jì)相對(duì)于其他的可視化來(lái)說(shuō)好像有些不足,目前似乎只有NetBeans支持
63、的比較好)。而且使用JAVA的條件是用戶(hù)必須安裝虛擬機(jī),并且JAVA的執(zhí)行速度在目前來(lái)看似乎也不太被看好。因此沒(méi)有考慮使用JAVA來(lái)完成本設(shè)計(jì)。</p><p> 2、整個(gè)工程使用C語(yǔ)言實(shí)現(xiàn)</p><p> 論速度而言,除開(kāi)低等的匯編,C語(yǔ)言絕對(duì)的獨(dú)占熬頭,并且C語(yǔ)言的語(yǔ)法簡(jiǎn)單,構(gòu)建出的程序結(jié)構(gòu)也清晰。結(jié)構(gòu)化的程序設(shè)計(jì)方式,也讓人自然而然的從上而下的去思考。其類(lèi)庫(kù)并且提供了大量的有關(guān)
64、網(wǎng)絡(luò)操作API,讓用戶(hù)能夠方便的使用并獲得所求的值。但C語(yǔ)言并沒(méi)有提供太多有關(guān)圖形設(shè)計(jì)方面的框架(或者是目前沒(méi)有用于C語(yǔ)言的應(yīng)用程序框架)。開(kāi)發(fā)者可能會(huì)花大量的時(shí)間在分析事件的流程上,而不是程序的邏輯。如此一來(lái),得不償失。</p><p> 因此,軟件采用MFC為應(yīng)用框架,配合IDE使用,能夠自動(dòng)提供出一套功能有限但設(shè)計(jì)結(jié)構(gòu)清晰的標(biāo)準(zhǔn)Windows程序。使用開(kāi)發(fā)語(yǔ)言為C++,是典型的面向?qū)ο笤O(shè)計(jì)語(yǔ)言。利用其面向
65、對(duì)象的特性,在開(kāi)發(fā)過(guò)程中能夠方便的向軟件添加功能。因此,在該程序的設(shè)計(jì)過(guò)程中,選取了C++作為開(kāi)發(fā)語(yǔ)言,VC++6.0作為程序設(shè)計(jì)的IDE。在本軟件過(guò)程中,定義了CSMTP、CMailMessage、CMIMEMessage、CBASE64 四個(gè)工具類(lèi),給程序使用。整個(gè)程序就是使用了MFC提供的應(yīng)用程序框架,并在其中添加了上述幾個(gè)工具類(lèi),相互協(xié)調(diào)工作而得來(lái)。結(jié)構(gòu)清晰,功能相對(duì)完備,既完成了預(yù)期的需求,也學(xué)習(xí)到了有關(guān)SMTP協(xié)議的知識(shí)。&
66、lt;/p><p><b> 各模塊設(shè)計(jì)</b></p><p> 實(shí)現(xiàn)SMTP協(xié)議的核心類(lèi)庫(kù)</p><p> 如上所述,目前與SMTP協(xié)議有關(guān)的核心類(lèi)共四個(gè),對(duì)于郵件的所有操作,均封裝在四個(gè)工具類(lèi)中。按照其完成的功能進(jìn)行劃分,每個(gè)工具類(lèi)都可以作為一個(gè)子模塊。四個(gè)子模塊各守其則,分別代表了某一種功能或?qū)嶓w。</p><p
67、> 一、CSMTP子模塊:該模塊封裝了有關(guān)郵件發(fā)送過(guò)程的操作。使用該模塊可以建立或斷開(kāi)與服務(wù)器的連接、向服務(wù)器發(fā)送消息、從服務(wù)器接受消息并分析得到的消息代碼是否正確、在服務(wù)器返回錯(cuò)誤消息時(shí)獲取到該消息。對(duì)于SMTP的分析以及發(fā)送時(shí)發(fā)送端與接收端之間的會(huì)話,均由此類(lèi)完成。該類(lèi)提供了兩個(gè)重要的程序接口Connect和TransmitMessage。其他模塊只需調(diào)用其接口方法,并傳遞正確的參數(shù),就可以方便的與服務(wù)器建立連接,并傳送郵件
68、內(nèi)容。由于當(dāng)前大多數(shù)SMTP服務(wù)器都已經(jīng)要求用戶(hù)進(jìn)行身份驗(yàn)證,因此在該類(lèi)中還封裝了對(duì)發(fā)送者身份驗(yàn)證的操作。</p><p><b> 成員變量說(shuō)明:</b></p><p> private BOOL m_bConnected:私有成員變量,表示當(dāng)前是否與服務(wù)器連接。TRUE表示已連接;FALSE表示沒(méi)有進(jìn)行連接。</p><p> pr
69、ivate UINT m_nPort:私有成員變量,表示與服務(wù)器連接的端口。在該軟件中該值為25。表示使用服務(wù)器的25號(hào)端口。</p><p> private CString m_nSMTPServerHostName:私有成員變量,表示服務(wù)器的名稱(chēng)。例如:smtp.163.com。</p><p> private CSocket m_SMTPServer:私有成員變量,表示連接到
70、服務(wù)器的網(wǎng)絡(luò)實(shí)體。</p><p> private CStringList * m_psErrorList:私有成員變量,是用于存放產(chǎn)生的錯(cuò)誤消息的列表。</p><p> protected TCHAR* responseBuf:保護(hù)成員變量,用于存放服務(wù)器返回的消息。</p><p> protected static ResponseCode* res
71、ponseTable[]:保護(hù)的靜態(tài)成員變量,代表消息碼與對(duì)應(yīng)消息的映射表。</p><p><b> 成員函數(shù)說(shuō)明:</b></p><p> 1)private BOOL GetResponse(UINT responseExpected):該方法根據(jù)獲取的UINT類(lèi)型的參數(shù)responseExpected來(lái)判斷所進(jìn)行的操作是否正確。在該方法中客戶(hù)端接收從服
72、務(wù)器發(fā)送來(lái)的消息,并進(jìn)行解析,然后根據(jù)給定的參數(shù)responseExpected來(lái)進(jìn)行判斷。如果判斷正確,那么返回TRUE;否則返回FALSE。</p><p> 2)public void SetServerProperties(CString szSMTPServerName , UINT nPort=SMTP_PORT):該方法根據(jù)獲得的字符串類(lèi)型和UINT類(lèi)型參數(shù)來(lái)設(shè)置要連接的服務(wù)器的名稱(chēng)以及端口號(hào)。
73、其中szSMTPServerName是服務(wù)器的名稱(chēng),nPort是端口號(hào)。其默認(rèn)值為SMTP_PORT 25。</p><p> 3)public CString GetLastError():通過(guò)調(diào)用該方法,能夠獲取服務(wù)器返回的錯(cuò)誤信息。如果沒(méi)有錯(cuò)誤信息,則返回空。</p><p> 4)public UINT GetPort():獲取服務(wù)器的端口號(hào)。</p><
74、;p> 5)public BOOL Connect():連接服務(wù)器方法。通過(guò)該方法,可以根據(jù)SetServerProperties方法設(shè)置的屬性,連接到指定的服務(wù)器。如果連接成功則返回TRUE;否則返回FALSE。</p><p> 6)public virtual BOOL TransmitMessgae(CMailMessage * msg):該方法的作用是根據(jù)傳遞進(jìn)來(lái)的CMailMessage
75、對(duì)象傳送郵件。在該方法中封裝了郵件發(fā)送的操作并對(duì)SMTP協(xié)議規(guī)定的命令和應(yīng)答碼的交互操作做了實(shí)現(xiàn),而且與郵件發(fā)送有關(guān)的身份驗(yàn)證操作也在該方法中實(shí)現(xiàn)。本方法的參數(shù)msg應(yīng)包含就是要發(fā)送的郵件的信息,如發(fā)送的來(lái)源、目的地、郵件的題目、發(fā)送時(shí)間、正文內(nèi)容以及附件,均存儲(chǔ)在msg對(duì)象中。在發(fā)送過(guò)程中,順序發(fā)送命令:AUTH LOGIN、MAIL FROM 、RCPT TO(可重復(fù)多次)、DATA (結(jié)束符CRLF.CRLF)、QUIT,并在每次
76、發(fā)送后設(shè)置一個(gè)接收指令,用于接收從服務(wù)器傳回的數(shù)據(jù),并進(jìn)行分析。如果是預(yù)期的數(shù)據(jù)那么返回TRUE,標(biāo)志發(fā)送成功;如果返回FALSE,標(biāo)志發(fā)送失敗。</p><p> 7)private CString CookBody(CMailMessage * msg):該方法用于剔除在郵件正文以及郵件中與結(jié)束標(biāo)志沖突的字符。在SMTP協(xié)議中規(guī)定:郵件正文以DATA命令開(kāi)始,以“CRLF.CRLF”標(biāo)志結(jié)束,為了避免在郵
77、件正文中,出現(xiàn)上述的結(jié)束標(biāo)志,必須在發(fā)送郵件前檢測(cè)郵件,把郵件中所有的與郵件結(jié)束符號(hào)相同的字符替換為“CRLF..CRLF”,來(lái)避免在郵件發(fā)送時(shí)出現(xiàn)結(jié)束位置不明的錯(cuò)誤。當(dāng)郵件發(fā)送到服務(wù)器后,會(huì)自動(dòng)的把郵件正文中的被替換的字符換回為原來(lái)的字符,從而保證郵件的正確性。該方法的參數(shù)為CMailMessage*類(lèi)型的指針,代表一個(gè)郵件對(duì)象。該對(duì)象包含有關(guān)的郵件信息,方便在本方法中對(duì)要發(fā)送的郵件進(jìn)行操作。</p><p>
78、 8)protected static ResponseCode* GetServerResponseMessage(UINT):該方法的作用是根據(jù)傳遞進(jìn)來(lái)的消息碼來(lái)返回一個(gè)與消息碼對(duì)應(yīng)的服務(wù)器消息。該方法采用查表的方式,根據(jù)郵件服務(wù)器發(fā)送的消息,來(lái)確定返回消息的具體信息,該方法主要在郵件操作出錯(cuò)時(shí),提供錯(cuò)誤信息。如果查表成功,返回一個(gè)合適的出錯(cuò)信息;如果查表失敗,則返回未知錯(cuò)誤。有關(guān)應(yīng)答碼和與應(yīng)答碼相關(guān)信息,均在本類(lèi)的靜態(tài)成員變量
79、ResponseCode responseTable中做了規(guī)定。</p><p> 二、CMailMessage子模塊:該模塊用于表示郵件的所有內(nèi)容,如:郵件的發(fā)送者、接收者、標(biāo)題、正文以及附件。該類(lèi)的設(shè)計(jì)借鑒了JAVA中JavaBean的定義方式,對(duì)私有數(shù)據(jù)進(jìn)行封裝只能通過(guò)對(duì)應(yīng)的方法進(jìn)行存取。使用本類(lèi)提供了能夠?qū)︵]件內(nèi)容進(jìn)行規(guī)范化設(shè)計(jì)的操作,使用這些操作能夠得到滿足SMTP協(xié)議規(guī)定的電子郵件。</p&g
80、t;<p><b> 成員變量說(shuō)明:</b></p><p> public CPtrArray m_Attachments:公有成員變量,表示郵件的附件。使用MFC提供的CPtrArray類(lèi)型變量,能夠方便的存儲(chǔ)多個(gè)附件的信息。</p><p> public CString m_AttachmentString:表示附件文件的名稱(chēng),在給該類(lèi)的對(duì)
81、象添加有關(guān)的附件信息的時(shí)候使用。</p><p> protected CString m_sSubject、m_sFrom、m_sTo、m_sHeader、m_sBody、m_sPassword、CTime m_tDateTime:表示郵件的信息,分別為:郵件的標(biāo)題、郵件發(fā)送者、郵件接收者、郵件頭信息、郵件體正文、身份驗(yàn)證的密碼以及郵件發(fā)送的時(shí)間。對(duì)于每個(gè)域均有一對(duì)對(duì)應(yīng)的存取方法Get和Set來(lái)對(duì)其進(jìn)行操作。
82、這設(shè)計(jì)的方式參考了JAVA中的JavaBean的設(shè)計(jì)模式。方便調(diào)用者使用該類(lèi)。</p><p> private CArray <CRecipient,CRecipient&> m_Recipients:私有成員變量。表示郵件接收者的一個(gè)數(shù)組。在SMTP協(xié)議中規(guī)定:一封郵件可以有多個(gè)接收者,每個(gè)接收者需要一個(gè)RCPT TO命令與之對(duì)應(yīng)。該變量就是用于存儲(chǔ)多個(gè)接收者的。</p>
83、<p><b> 成員函數(shù)說(shuō)明:</b></p><p> 1)public int AddAttachMent(CString filename):該方法的作用是添加根據(jù)參數(shù)提供的文件名稱(chēng),把該文件當(dāng)成附件添加到當(dāng)前的郵件中。返回值為郵件中已有的附件的個(gè)數(shù)。該方法有一個(gè)重載方法,參數(shù)為CMIMEMessage*,作用是把一個(gè)附件添加到當(dāng)前郵件。返回值與該方法意義相同。<
84、;/p><p> 2)public int GetAttachmentNum():該方法的作用是獲取當(dāng)前附件的個(gè)數(shù)。</p><p> 3)public int GetNumberRecipients(RECIPIENTS_TYPE type=TO):作用是獲取當(dāng)前的接收者的數(shù)目。參數(shù)是接收者的類(lèi)型,默認(rèn)值是TO類(lèi)型,意為普通的接收者。參數(shù)type是個(gè)enum RECIPIENT_TY
85、PE類(lèi)型的變量,有三個(gè)合法值,分別為:TO,CC,BCC。分別代表:普通接收者,抄送和密送。對(duì)于后兩個(gè)值,本版本沒(méi)有提供支持。</p><p> 4)BOOL AddRecipient(LPCTSTR szEmailAddress , LPCTSTR szFriendlyName="" , RECIPIENTS_TYPE type=TO):作用是向郵件添加接收者信息。默認(rèn)的接收者類(lèi)型為T(mén)O
86、,也是當(dāng)前版本唯一能夠支持的類(lèi)型。szEmailAddress表示郵件的地址,szFriendlyName表示名稱(chēng)。</p><p> 5)public void AddToHeader(CString sTemp):該方法作用是向郵件添加頭信息。傳遞的參數(shù)為要向郵件添加的頭信息。</p><p> 6)public virtual void PrepareHeader():本方法
87、的作用是根據(jù)對(duì)象本身的成員變量來(lái)生成郵件頭。根據(jù)SMTP協(xié)議的規(guī)定,郵件的頭包括:From、To(可重復(fù)多次)、Subject、Date、X-Mailer、MIME-Version: 、Content-type等多個(gè)域。這些域構(gòu)成了郵件頭的信息。只有正確包含上述域的郵件才能被郵件服務(wù)器接收。這些域的生成均包含在了該方法的實(shí)現(xiàn)中,通過(guò)調(diào)用該方法就可以獲得一個(gè)滿足SMTP協(xié)議要求的郵件頭。</p><p> 7)
88、public virtual void PrepareBody():該方法的作用是生成一個(gè)滿足SMTP協(xié)議的郵件體。根據(jù)SMTP協(xié)議的規(guī)定:郵件的正文和附件消息均要滿足固定的格式。并且郵件正文與附件、附件與附件之間要有正確的分隔標(biāo)志。該方法中規(guī)定的郵件分隔標(biāo)志為#BOUNDARY#,該標(biāo)志由PrepareHeader()方法中定義。在方法中,根據(jù)當(dāng)前添加的郵件附件的個(gè)數(shù)來(lái)添加標(biāo)志。所有附件添加結(jié)束后,會(huì)添加一個(gè)為“--#BOUNDARY
89、#--”的結(jié)束符號(hào)。標(biāo)志郵件正文的結(jié)束。</p><p> 三、CMIMEMessage子模塊:該模塊用于表示郵件的附件。使用該類(lèi)可以根據(jù)提供的文件名讀取出正確的文件,保存文件名和標(biāo)題。并提供了能夠取出這些屬性的方法。</p><p><b> 成員變量說(shuō)明:</b></p><p> 1)protected CString m_Fil
90、ename:保護(hù)成員變量,表示附件所代表的文件的文件名。添加到郵件時(shí)使用。</p><p> 2)protected CString m_FileContent、TCHAR * m_ContentBuffer:保護(hù)成員變量,表示附件所代表的文件的內(nèi)容。</p><p> 3)protected DWORD bufLen:保護(hù)成員變量,表示當(dāng)前附件的長(zhǎng)度,單位是字節(jié)。</p&g
91、t;<p><b> 成員函數(shù)說(shuō)明:</b></p><p> 1)public BOOL Attach(const CString &sFilename):該方法的作用是根據(jù)傳遞進(jìn)來(lái)的參數(shù)文件名,來(lái)把本地文件中的內(nèi)容讀取出來(lái),并添加到當(dāng)前附件對(duì)象中。并且根據(jù)傳遞進(jìn)來(lái)的參數(shù),分別給bufLen、m_FileContent、m_Filename、m_Title等成員
92、變量賦值。如果附件添加成功,則返回TRUE;否則返回FALSE。</p><p> 2)public CString GetFilename()、CString GetTitle()、CString GetContent()、TCHAR * GetContentBuffer()、DWORD GetBufferLength():上述方法作用分別為獲取附件名稱(chēng)、附件標(biāo)題、附件內(nèi)容(以字符串形勢(shì)返回)、附件內(nèi)容(以
93、數(shù)組方式返回)、附件的長(zhǎng)度。為類(lèi)的調(diào)用者提供了統(tǒng)一的操作接口。</p><p> 四、CBASE64子模塊:在SMTP的相關(guān)協(xié)議中規(guī)定,對(duì)于身份驗(yàn)證的用戶(hù)名、密碼、郵件的正文以及附件的內(nèi)容均要采用BASE64的方式進(jìn)行編碼。該類(lèi)就是對(duì)BASE64的算法進(jìn)行的封裝。提供了對(duì)兩種數(shù)據(jù)源的加密操作和一種解密操作。</p><p><b> 成員變量說(shuō)明:</b><
94、/p><p> 1)static CString base64:該變量是歸類(lèi)所屬的成員變量。表示BASE64編碼所使用的字符表。</p><p> 2)private CString sEncode 、CString sDecode:表示編碼和解碼的數(shù)據(jù)。</p><p><b> 成員函數(shù)說(shuō)明:</b></p><p
95、> 1)public DWORD CBASE64::ComputeLen(DWORD size):該方法的作用是計(jì)算編碼后數(shù)據(jù)的長(zhǎng)度。參數(shù)為編碼前的長(zhǎng)度,返回值為編碼后的長(zhǎng)度。</p><p> 2)TCHAR * CBASE64::Encode(TCHAR* buf , DWORD nSize):該方法的作用是對(duì)制定的數(shù)據(jù)進(jìn)行編碼。參數(shù)TCHAR *buf表示要進(jìn)行編碼的數(shù)據(jù)的首地址,參數(shù)DWOR
96、D nSize則表示要編碼的長(zhǎng)度。本方法根據(jù)BASE64編碼的定義,對(duì)數(shù)據(jù)進(jìn)行了編碼。本類(lèi)為該方法提供了一個(gè)重載的方法,其參數(shù)為CString szEncoding和int nSize。參數(shù)szEncoding表示要進(jìn)行編碼的數(shù)據(jù)源,而參數(shù)int nSize表示要進(jìn)行編碼的長(zhǎng)度。在兩種方法中,返回值均為編碼后的數(shù)據(jù)。</p><p> 3)char * CBASE64::GetTempSecret(CStr
97、ing sTemp , int &length):根據(jù)BASE64編碼方式的定義,在解碼過(guò)程中,要先把要編碼后的數(shù)據(jù)根據(jù)BASE64的對(duì)應(yīng)表變換成編碼時(shí)所得到的中間碼。該方法就是根據(jù)編碼后的數(shù)據(jù)得到中間碼的操作。參數(shù)CString sTemp和int &length分別為要解碼的數(shù)據(jù)和長(zhǎng)度。</p><p> 4)CString CBASE64::Decode(CString szDecodi
98、ng , int nSize):該方法的作用是根據(jù)傳遞進(jìn)來(lái)的參數(shù)對(duì)數(shù)據(jù)進(jìn)行解碼。</p><p><b> 模塊之間的關(guān)系</b></p><p> 本軟件是由各個(gè)工具類(lèi)和界面類(lèi)兩個(gè)大部分構(gòu)成的。其中界面類(lèi)由MFC自動(dòng)創(chuàng)建,而工具類(lèi)則由作者設(shè)計(jì)完成,整個(gè)軟件的開(kāi)發(fā)過(guò)程就是把工具類(lèi)添加進(jìn)界面類(lèi)并使之能夠協(xié)調(diào)工作的過(guò)程(開(kāi)發(fā)者的工作都是這樣)。正如上節(jié)提到的,CMyE
99、MailApp是整個(gè)應(yīng)用程序的入口,在其初始化操作中調(diào)用了CMyEMailDlg的相關(guān)方法,生成主界面對(duì)話框。在主界面對(duì)話框的相關(guān)事件處理方法中,會(huì)調(diào)用CSMTP的連接和傳送消息方法,并把用戶(hù)輸入的數(shù)據(jù)裝配為一個(gè)完整的CMailMessage消息供CSMTP使用。而如果在存在附件的情況下,CMailMessage類(lèi)型的消息則會(huì)包含一個(gè)CMIMEMessage類(lèi)型的附件。在CSMTP和CMailMessage中又會(huì)看到,它們對(duì)CBASE6
100、4類(lèi)的調(diào)用。整個(gè)軟件就是由這樣的一些類(lèi)有機(jī)“堆砌”而成。類(lèi)的關(guān)系圖如圖4-1所示。</p><p><b> 圖4-1類(lèi)關(guān)系圖</b></p><p> 核心模塊實(shí)現(xiàn)與核心功能編碼</p><p><b> 郵件發(fā)送實(shí)現(xiàn)</b></p><p> 在郵件發(fā)送之前首先要與服務(wù)器建立連接,該操作
101、由CSMTP類(lèi)的Connect操作完成。該方法根據(jù)用戶(hù)輸入的參數(shù),調(diào)用底層API連接到服務(wù)器,連接失敗返回FALSE,連接成功則返回TRUE。</p><p> //首先要建立接收消息緩沖區(qū),接收服務(wù)器的消息</p><p> this->responseBuf = new TCHAR[RESPONSE_BUFFER_SIZE];</p><p> //
102、創(chuàng)建連接,成功繼續(xù)執(zhí)行,失敗則返回。</p><p> if( !this->m_SMTPServer.Create())</p><p> //用用戶(hù)指定的服務(wù)器和端口號(hào)碼連接到服務(wù)器,成功繼續(xù)執(zhí)行;失敗返回</p><p> if( !this->m_SMTPServer.Connect(p,this->GetPort()))</p
103、><p> //接收服務(wù)器發(fā)送的消息代碼,為220說(shuō)明服務(wù)器接受了請(qǐng)求,否則出錯(cuò)</p><p> if(!this->GetResponse(SMTP_SERVER_READY) )</p><p> //發(fā)送EHLO命令給服務(wù)器,要求建立一條通信通道</p><p> helloCommand.Format("EHLO
104、 %s\r\n" , localHostName);</p><p> this->m_SMTPServer.Send((LPCTSTR)helloCommand,helloCommand.GetLength());if( !this->GetResponse(SMTP_SERVER_TASK_FINISH) )</p><p> 如果在上述過(guò)程中沒(méi)有出錯(cuò),那么就
105、得到了一條客戶(hù)端與服務(wù)器進(jìn)行信息交互的通道。利用該通道就可以進(jìn)行郵件傳送操作了。綜上所述,建立與服務(wù)器連接過(guò)程程序流程圖如圖4-2所示。</p><p> 圖4-2 建立與服務(wù)器連接算法流程圖</p><p> 通過(guò)上述操作,連接建立結(jié)束,接下來(lái)的工作就是傳送數(shù)據(jù)了。相關(guān)的操作是在CSMTP類(lèi)中的TransmitMessage方法中完成的。方法如下:</p><p&
106、gt; //首先判斷連接是否已經(jīng)建立</p><p> //如果連接已經(jīng)建立,那么就繼續(xù)進(jìn)行下面的操作;否則返回錯(cuò)誤信息</p><p> if( !this->m_bConnected )</p><p> //發(fā)送身份驗(yàn)證命令。發(fā)送后等待服務(wù)器的回復(fù),如果回復(fù)為AUTH_OK,</p><p> //那么繼續(xù)下面的操作,否
107、則返回錯(cuò)誤信息</p><p> sAuth.Format( _T("AUTH LOGIN\r\n") ) ;</p><p> this->m_SMTPServer.Send( (LPCTSTR)sAuth , sAuth.GetLength() );</p><p> if( !this->GetResponse(AUTH_
108、OK) )</p><p> //使用CBASE64對(duì)用戶(hù)名進(jìn)行加密并發(fā)送</p><p> CString username = cBase.Encode( sFrom , sFrom.GetLength() )+"\r\n" ;</p><p> this->m_SMTPServer.Send((LPCTSTR)username
109、, username.GetLength());</p><p> if( !this->GetResponse(AUTH_OK) ) </p><p> //使用CBASE64對(duì)密碼進(jìn)行加密并發(fā)送,如果驗(yàn)證成功,服務(wù)器會(huì)返回</p><p> //AUTH_SUCCESSFULLY來(lái)標(biāo)識(shí)。否則返回錯(cuò)誤。</p><p> pa
110、ssword = cBase.Encode(password , password.GetLength())+"\r\n";</p><p> this->m_SMTPServer.Send((LPCTSTR)password , password.GetLength());</p><p> if( !this->GetResponse(AUTH_SU
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 網(wǎng)絡(luò)爬蟲(chóng)的設(shè)計(jì)與實(shí)現(xiàn)畢業(yè)論文(含外文翻譯)
- 畢業(yè)論文-寬帶點(diǎn)播設(shè)計(jì)與實(shí)現(xiàn)(含外文翻譯)
- 網(wǎng)絡(luò)爬蟲(chóng)的設(shè)計(jì)與實(shí)現(xiàn)畢業(yè)論文(含外文翻譯)
- flash畢業(yè)論文(含外文翻譯)
- 物流專(zhuān)業(yè)畢業(yè)論文(含外文翻譯)
- 礦井通風(fēng)畢業(yè)論文(含外文翻譯)
- 移動(dòng)車(chē)輛管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)畢業(yè)論文(含外文翻譯)
- 郵件快速分揀系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)畢業(yè)論文(含外文翻譯)
- 畢業(yè)論文---高校超市管理系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)(含外文翻譯)
- 汽車(chē)營(yíng)銷(xiāo)策略畢業(yè)論文(含外文翻譯)
- 醫(yī)院住院反饋系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)畢業(yè)論文(含外文翻譯)
- 在線考試系統(tǒng)畢業(yè)論文(含外文翻譯)
- 電腦橫機(jī)畢業(yè)論文(含外文翻譯)
- 工程管理專(zhuān)業(yè)畢業(yè)論文(含外文翻譯)
- 航海過(guò)失免責(zé)畢業(yè)論文(含外文翻譯)
- 無(wú)砂混凝土畢業(yè)論文(含外文翻譯)
- 郵件系統(tǒng)畢業(yè)論文(含外文翻譯)
- 管道監(jiān)測(cè)系統(tǒng)畢業(yè)論文(含外文翻譯)
- 機(jī)床夾具設(shè)計(jì)畢業(yè)論文(含外文翻譯)
- 小區(qū)給排水畢業(yè)論文(含外文翻譯)
評(píng)論
0/150
提交評(píng)論