注銷

          注銷

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            112 隨筆 :: 7 文章 :: 18 評論 :: 0 Trackbacks

          用C#.NET實現(xiàn)電子郵件客戶程序

          周華清 戴晟輝(東華理工學院計算機與通信系 江西 撫州 344000)

          【摘要】通過C#這種VisualSTudio.NET中新引入的面向?qū)ο笄翌愋桶踩木幊陶Z言,在.NET平臺上開發(fā)電子郵件客戶程序。通過套接字編程實現(xiàn)網(wǎng)絡(luò)通信連接,闡述SMTP(簡單郵件傳輸協(xié)議)和POP3(郵局協(xié)議)的工作原理,然后具體講解了根據(jù)SMTP協(xié)議開發(fā)電子郵件客戶端的郵件發(fā)送程序,根據(jù)POP3協(xié)議開發(fā)電子郵件客戶端的郵件接收程序。

          【關(guān)鍵詞】套接字? 簡單郵件傳輸協(xié)議? 郵局協(xié)議

          1 C#中套接字的編程

          套接字是通信的基石,是支持TCP/IP協(xié)議網(wǎng)絡(luò)通信的基本操作單元。可以將套接字看做不同主機間的進程進行雙向通信的端點,它構(gòu)成了單個主機內(nèi)及整個網(wǎng)絡(luò)間的編程界面。套接字存在于通信域中。通信域是為了處理一般的線程通過套接字通信而引進的一種抽象概念。套接字通常和同一個域中的套接字交換數(shù)據(jù)(數(shù)據(jù)交換也可能穿越域的界限,但這時一定要執(zhí)行某種解釋程序)。各種進程使用這個相同的域互相之間用Internet協(xié)議簇來進行通信。

          針對C#中Socket編程用Socket類來進行,.NET 框架的Socket類是包含在System.Net.Sockets名字空間中的一個非常重要的類,其中為實現(xiàn)網(wǎng)絡(luò)編程提供了大量的方法。使用Socket類開發(fā)windows網(wǎng)絡(luò)應(yīng)用程序原來有規(guī)可尋,它們在大多數(shù)情況下遵循大致相同的步驟。

          在使用之前,你需要首先創(chuàng)建Socket對象的實例,這可以通過Socket類的構(gòu)造方法來實現(xiàn):

          public Socket(AddressFamily addressFamily,SocketType socketType,ProtocolType protocolType);

          其中,addressFamily參數(shù)指定Socket使用的尋址方案;socketType參數(shù),指定Socket的類型;protocolType參數(shù),指定Socket使用的協(xié)議。

          下面的示例語句創(chuàng)建一個Socket,它可用于在基于TCP/IP的網(wǎng)絡(luò)(如Internet)上通訊。

          Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

          若要使用UDP而不是TCP,需要更改協(xié)議類型,如下面的示例所示:

          Socket s=newSocket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

          一旦創(chuàng)建Socket,在客戶端,將可以通過Connect方法連接到指定的服務(wù)器,并通過Send/SendTo方法向遠程服務(wù)器發(fā)送數(shù)據(jù),而后可以通過Receive/ReceiveFrom方法從服務(wù)端接收數(shù)據(jù);而在服務(wù)器端,你需要使用Bind方法綁定所指定的接口使Socket與一個本地終結(jié)點相聯(lián),并通過Listen方法偵聽該接口上的請求,當偵聽到用戶端的連接時,調(diào)用Accept完成連接的操作,創(chuàng)建新的Socket以處理傳入的連接請求。使用完Socket后,記住使用Shutdown方法禁用Socket,并使用Close方法關(guān)閉Socket。

          ?2 SMTP和POP3協(xié)議的工作過程

          在Internet上發(fā)送/接收電子郵件,要用到二個協(xié)議:SMTP(簡單郵件傳輸協(xié)議)和POP3(郵局協(xié)議)。下面從SMTP和POP3協(xié)議入手,說明如何發(fā)送和接收電子郵件。

          如圖1,描述了從發(fā)件人使用主機(Client1)發(fā)送一封郵件從郵箱one@server1.com發(fā)往郵箱two@server2.com(其中域名為server1.com的郵件系統(tǒng)安裝在Server1上,域名為server2.com的郵件系統(tǒng)安裝在Server2上),收件人通過主機(Client2)接收到這封郵件的過程。在郵件傳送的各個階段要采用不同的網(wǎng)絡(luò)協(xié)議。???

          (1)發(fā)件人采用Mail Client端軟件在Client 1處撰寫一封郵件發(fā)給收件人,首先是將該郵件從Client1發(fā)送到他本人的郵箱one@server1.com所在的服務(wù)器Server1上。這一步由Client1發(fā)往Server的過程采用的是SMTP協(xié)議。

          ?

          ????????????????????????? 圖1 電子郵件傳送過程示意圖

          (2)郵件可以從發(fā)件人的郵件服務(wù)器Server1直接傳送到收件人郵箱two@server2.com所在的服務(wù)器Server2上,也可能需要經(jīng)過第三方的郵件服務(wù)器Server3做中轉(zhuǎn)后再送達接收方,這個過程稱為Relay。這一步在Mail Server之間進行郵件傳送的過程采用的是SMTP協(xié)議。郵件發(fā)送到接收方的服務(wù)器Server2上后,由Server2負責將該郵件投遞到收件人的郵箱two@server2.com中,保存在Server2的磁盤陣列中。此時,郵件傳送過程結(jié)束。

          (3)收件人訪問他在Server2上的郵箱two@server2.com時,采用Mail Client端軟件Client2將Server2郵箱中的郵件下載到本地硬盤上閱讀。這一步將郵件從Server下載到Client的過程采用的是POP3協(xié)議。

          開發(fā)電子郵件客戶端實際上也就是利用套接字(Socket)編程進行對話通訊,按照SMTP協(xié)議和POP3協(xié)議的規(guī)范完成郵件傳輸。

          3 郵件發(fā)送模塊的實現(xiàn)

          ?SMTP協(xié)議是TCP/IP協(xié)議棧中的一個廣為使用的上層協(xié)議。SMTP定義了如何在兩個用戶間傳輸郵件,使用了spooling的概念,允許將郵件從一個本地應(yīng)用發(fā)送到一個SMTP應(yīng)用。SMTP應(yīng)用把郵件存儲到一個設(shè)備或內(nèi)存中,一旦郵件到達SMTP應(yīng)用,該郵件被放入到一個隊列中,一個服務(wù)器檢查是否有郵件到達,然后試圖投遞到達的郵件。如果郵件的收方不存在,服務(wù)器然后還會再進行嘗試。最終,如果郵件不能被投遞,則將該郵件丟棄或返回給郵件的發(fā)送者。這一概念被稱為端到端的投遞,并且它將郵件保存在隊列中,直到郵件被投遞出去。我們可以從兩個RFC中找到有關(guān)SMTP的討論。RFC822描述了報文的結(jié)構(gòu),其中還包括了信封。RFC821規(guī)定了在兩臺機器間控制郵件交換的協(xié)議。

          以下模塊利用TcpClient類開發(fā)一個SMTP客戶端,以發(fā)送郵件。

          3.1 發(fā)送SMTP命令

          SMTP服務(wù)器一般都識別UTF8碼,所有發(fā)送命令都使用UTF8編碼,每個命令均以回車換行符結(jié)束。下列代碼實現(xiàn)命令的發(fā)送功能。

          private void WriteToNetStream(ref NetworkStream NetStream.string Command)

          {? string stringToSend = Command + "\r\n";

          ?Byte[] arrayToSend = System.Text.Encoding.UTF8.GetBytes

          ??????? (stringToSend.ToCharArray());

          ?? NetStream.Write(arrayToSend,0,arrayToSend.Length);}

          3.2 答應(yīng)碼的接收

          SMTP服務(wù)器對每一個都發(fā)出響應(yīng)。下列代碼實現(xiàn)接受答應(yīng)碼的功能。

          private string ReadFromNetStream(ref NetworkStream NetStream)

          { byte[] bb=new byte[512];

          ? NetStream.Read(bb,0,bb.Length);

          ? string read=System.Text.Encoding.UTF8.GetString(bb);}

          ?3.3 應(yīng)答碼檢查

          發(fā)送郵件客戶端必須要檢查應(yīng)答碼,以判斷服務(wù)器是否已經(jīng)執(zhí)行了命令。如果服務(wù)器沒有執(zhí)行,則重新發(fā)送命令或采用其他措施。下列代碼可以檢查服務(wù)器是否正確地執(zhí)行了命令。

          private string checkForError(string strMessage,string check)

          {? if (strMessage.Indexof(check) == -1)

          ????? { return "err";}

          else{return "correct";}}

          上述方法的第一個參數(shù)是服務(wù)器返回信息,第二個參數(shù)是要檢查的答應(yīng)碼。如果服務(wù)器返回的信息中不存在第二個參數(shù)的字符串,則返回“err”,表明服務(wù)器沒正確執(zhí)行命令。

          ?3.4 發(fā)送郵件

          客戶端發(fā)出DATA命令,在服務(wù)器作出354應(yīng)答后,即可開始郵件內(nèi)容的發(fā)送。郵件以<CRLF>.<CRLF>結(jié)束。下列代碼實現(xiàn)了郵件發(fā)送功能。

          private void sendMail(ref NetworkStream NetStream, string message)

          {?? Byte[] attayToSend = System.Text.Encoding.UTF8.GetBytes

          (message.ToCharArray());

          ?? NetStream.Write(arrayToSend,0,arrayToSend.Length);}

          4 郵件接收模塊的實現(xiàn)

          POP允許本地郵件UA(User Agent,用戶代理)連接SERVER并將郵件取回到用戶本地系統(tǒng),用戶也在本地機上閱讀和響應(yīng)消息。POP3UA通過TCP/IP與服務(wù)器連接(通常使用端口110)。輸入用戶名和口令經(jīng)過認證后,UA可通過POP3命令取回或刪除郵件。POP3僅僅是接收協(xié)議。POP3UA使用SMTP向服務(wù)器發(fā)送郵件。

          利用POP3協(xié)議開發(fā)一個郵件接收程序,使用USER、PASS、STAT、LIST、RETR、DELE、QUIT命令。下面開始開發(fā)過程。

          ?4.1 發(fā)送命令碼

          ?在此發(fā)送命令碼也使用的是ASCII碼。下列方法用于向服務(wù)器發(fā)送命令碼:

          private void WriteToNetStream(ref NetworkStream NetStream.string Command)

          {?? string stringToSend = Command + "\r\n";

          ??? Byte[]arrayToSend= System.Text.Encoding.ASCII.GetBytes

          ??????????? (stringToSend.ToCharArray());

          ??? NetStream.Write(arrayToSend,0,arrayToSend.Length);}

          4.2 接收服務(wù)器應(yīng)答

          一般而言,接收服務(wù)器應(yīng)答,既可使用ASCII碼,也可以使用UTF8碼,這里使用的是ASCII碼。下列方法用于接受服務(wù)器的應(yīng)答。

          private string ReadFromNetStream(ref NetworkStream NetStream)

          {? byte[] bb=new byte[1024];

          ?? NetStream.Read(bb,0,bb.Length);

          ?? string read=System.Text.Encoding.ASCII.GetString(bb);

          ?? return read;}

          4.3 接受郵件

          在此接收郵件用UTF8碼,當遇到<CRKF>.<CRLF>,則結(jié)束讀取數(shù)據(jù)。下列代碼用于接收郵件:

          private void ReadMail(ref NetworkStream NetStream,int number)

          {? int k=0;

          ?? bool check=false;

          ?? byte[] bb=new byte[6400];

          ?? while(!check)

          ???? { k=NetStream.Read(bb,0,bb.Length);

          ?? string read=System.Text.Encoding.UTF8.GetString(bb,0,k);

          ?????? int x= read.IndexOf("\r\n.\r\n");

          ?????? if(x!=-1)

          ????????? { check=true;}

          ????????? richTextBox2.AppendText(read);

          ????????? WriteToNetStream(ref

          ?NetStream,"DELE "+number.ToString());

          ????????? string back=ReadFromNetStream(ref NetStream );

          ??????? richTextBox1.AppendText("DELE "+number.ToString()

          +"命令應(yīng)答:"+back+"\r\n"); }}

          5 結(jié)束語

          把郵件發(fā)送模塊和郵件接收模塊合起來,就成為一個電子郵件的客戶端程序。在實際應(yīng)用中,在上面基礎(chǔ)上加以改進,如果再進一步結(jié)合數(shù)據(jù)庫技術(shù),這可以開發(fā)出易用、可靠的電子郵件的客戶端程序。

          (收稿日期:2004-02-25;電子郵件:zhouhuaqing@peoplemail.com.cn

           

          Programming e-mail client with c#.net

          Abstract: Develop a program for e-mail client on the flat of .net with C#. C# is a new language of visual studio .net , is modern, object-oriented and is safe in type. Realize the network correspondence depending Socket programming. Expatiate the principle of SMTP(Simple Mail Transfer Protocol) and POP3(Post office Protocol), then explain developing a program to send e-mail according to the SMTP agreement development E-mail mail customer and carry to receive the procedure developing a program to receive e-mail according to the POP3 in detail.

          Key Words: Socket; Simple Mail Transfer Protocol; Post Office Protocol

          參 考 文 獻

          [1]謝希仁. 計算機網(wǎng)絡(luò). 第2版. 北京:清華大學出版社,1999

          [2]Charles Petzold. Windows程序設(shè)計. 第5版. 北京:北京大學出版社,1999

          [3]Anthony Jones 和 Jim Ohlund.? Windows網(wǎng)絡(luò)編程. 第2版. 北京:清華大學出版社,2002

          posted on 2006-10-21 23:02 注銷..... 閱讀(3452) 評論(1)  編輯  收藏 所屬分類: 閱讀摘要

          評論

          # re: 用C#.NET實現(xiàn)電子郵件客戶程序 2009-01-22 14:40 易勇
          你只寫了一些相關(guān)的,怎么不把源碼公布出來,

          對于一個不懂通信協(xié)議的人來說,你這樣寫,還是不能理解的。。

          我是一個不懂通信協(xié)議的人。。 工作需要寫個這郵件系統(tǒng)。。

          你可以把收郵件的部分給我詳解嗎 ? 我連該導(dǎo)什么包我都不知道的 。。。。

          謝謝


          我的msn gggg747636@live.cn  回復(fù)  更多評論
            

          主站蜘蛛池模板: 砀山县| 新安县| 福州市| 莫力| 凌海市| 繁峙县| 青岛市| 金湖县| 闸北区| 唐海县| 和田县| 万年县| 偏关县| 璧山县| 嘉荫县| 鹤庆县| 乌拉特前旗| 北票市| 名山县| 石景山区| 大方县| 商都县| 集贤县| 汝州市| 郁南县| 华亭县| 天气| 合肥市| 威海市| 青州市| 沂南县| 商城县| 西华县| 龙海市| 通榆县| 扎赉特旗| 大荔县| 西峡县| 城市| 神农架林区| 赣榆县|