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