精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

C#網絡編程系列十:實現簡單的郵件收發器

開發 后端
知道電子郵件的應用程序的原理也是非常有必要的,在這一個專題中將介紹電子郵件應用程序的原理、電子郵件應用程序中涉及的協議和實現一個簡答的電子郵件收發器程序。

引言:在我們的平常工作中,郵件的發送和接收應該是我們經常要使用到的功能的。因此知道電子郵件的應用程序的原理也是非常有必要的,在這一個專題中將介紹電子郵件應用程序的原理、電子郵件應用程序中涉及的協議和實現一個簡答的電子郵件收發器程序。

一、郵件應用程序基本知識

1.1 電子郵件原理及相關協議

說到電子郵件的原理,其實和我們現實生活中寄郵件和寄包裹是一樣的原理的。就讓我們先回顧下現實生活中寄郵件的流程吧——首先,我們先寫好信,信封上面寫好收信人的地址,寫信人的地址,然后把信放到寄信箱中,然后郵局的人會某個時候去這個信箱中的信取出來,然后郵局的人根據信封上寫的收信人地址進行轉發到當地的郵局,當地郵局然后把信寄到收信人的信箱中(寄包裹的話可能會電話聯系,像我們在淘寶,京東買的東西的,收貨人就是通過電話聯系一樣),最后收信人會到自己的信箱中收取信件。上面大致是我們平時生活中寄信的一個流程的。前面已經講過電子郵件的原理和這個差不多的,下面就介紹了本專題中電子郵件的原理,大家可以和現實生活中的寄信過程進行對比下的,這樣可以更加容易理解和掌握:

我們通過電子郵件應用(例如 基于客戶端的Outlook電子郵件軟件 和一些基于Web的電子郵件系統——新浪郵箱、谷歌郵箱、QQ郵箱等都屬于電子郵件應用)將一封寫好的郵件(相當于現實生活中的信,當然郵件也要寫明收件人地址,郵件內容等信息的)通過電子郵件協議(SMTP,在后面的電子郵件相關協議中會介紹)發送到SMTP服務器(就是存儲郵件的地方,相當于生活中的郵局一樣),然后SMTP服務器根據收件人的地址通過SMTP協議轉發到相應SMTP接收服務器上,(SMTP服務器進行轉發相當于現實生活中郵局的人配送信的過程,配送到收件人當地的郵局,然而現實生活中郵局都是一家,所以可以相互識別——意思就是發送到當地郵局,當地郵局會接收,并且幫助你發送到指定人的信箱中,在網上上就是通過SMTP協議來規定這樣的一個過程的,發送到別人的SMTP服務器上別人的服務器必須要認識發送來的郵件并接收)結束,接收端郵件服務器(POP3服務器)把郵件存放到接受者的電子信箱內(相當于當地郵局的人把信放到收信人的郵箱中),最后收件人可以登錄自己的電子信箱,再與POP3服務器進行連接,從POP3服務器上下載發送來的郵件,這樣在收件人的電子信箱中就可以看到發送來的電子郵件了(這就是現實生活中收信人從自己的信箱中取信的一個過程)。

注:括號中都是個人的理解,如果有什么不對的地方還望大家指出來,我好及時更正。

上面已經把電子郵件的原理和現實生活中寄信的過程進行對比,相信大家可以更加清楚電子郵件的原理和發送接收過程的,其實網絡上的很多應用都可以以現實生活的例子去理解,這樣的話我認為可以加深對知識的理解。下面就介紹下電子郵件中的相關協議的內容:

網絡上的應用的核心就是協議,因為協議讓網絡上的客戶端相互認識發生來的數據,所以電子郵件應用也不例外,也有相關的電子郵件協議來完成發送電子郵件和接收電子郵件的過程,這些協議主要是:SMTP(簡單郵件傳輸協議,Simple Mail Transfer Protocol)、POP3(郵局協議,Post Office Protocol)和IMAP(網絡郵件訪問協議,Internet Message Access Protocol)。

SMTP——SMTP 主要負責將郵件從一臺機器轉發至另一臺機器(可以對照上面電子郵件的過程來理解SMTP的作用)

POP3——3表示POP協議的版本,主要負責將郵件從郵箱中(POP3服務器)傳輸到本地計算機。

IMAP——現在常用的版本為第四版本,即IMAP4,主要負責郵件的檢索和處理功能,客戶端不需要下載郵件到本地計算機,可直接從郵件客戶端軟件對服務器上的信件和文件目錄進行操作,它是POP3的替代協議的。

1.2 郵件系統的分類

郵件系統主要分為兩類的——基于客戶端的郵件系統和基于Web瀏覽器的郵件系統。Office OutLook就是基于客戶端的郵件客戶端系統,而像我們經常使用的QQ郵箱、新浪、網易郵箱等都是屬于基于Web瀏覽器的郵件系統,基于客戶端的郵件系統的收發過程,通過下面的圖片來描述(圖片從網上摘下的):

圖 1.1 基于客戶端的郵件收發過程

發送方通過郵件客戶端,將編輯好的郵件向郵件服務(SMTP服務器,在發送過程中也叫發送端郵件服務器)發送,發送端郵件服務器根據收件人的地址來識別接收端郵件服務器(POP3服務器),然后向POP3服務器發送郵件信息,接收端郵件服務器將郵件存放在接收者的電子信箱中,并告知接收者有新郵件,接收者通過郵件客戶端與POP3服務器連接后,就可以查看新郵件。

然而,基于Web瀏覽器的郵件系統與基于客戶端的郵件系統不同的地方有:

基于Web瀏覽器郵件系統用戶代理(代理的概念也就是用戶不是直接與服務器進行通信,而是通過代理的方式,讓代理去與服務器通信,然后用戶在從代理中獲的服務器的信息,代理也就是中間人的作用,相當于生活中中介,在.net中很多技術都用到了代理,例如委托的概念其實也就是代理的一個概念的)是Web瀏覽器,基于客戶端的郵件系統而是郵件客戶端應用程序,一般是Windows Form程序。

瀏覽器發送郵件到SMTP服務器和從POP3服務器中獲得郵件的方式都是通過HTTP協議來實現,與基于客戶端的郵件系統不同(基于客戶端的郵件系統發送通過SMTP協議或ESMTP(Extended SMTP),獲得通過POP3或IMAP協議)。

1.3 目前主要的電子郵件服務系統

電子郵件服務系統——就是向大家提供郵箱服務的服務系統,這樣的系統當然是由專門的公司進行研發的,我們一般叫這樣的公司為郵件服務商,我們平常使用的網易郵箱,新、Gmail郵箱等都是建立在電子郵件服務系統(這里我的理解是——我們使用的新浪,網易等郵箱相當于現實生活中每個人的信箱,通過信箱可以獲得郵局來的信,同樣道理通過郵箱可以獲得郵件服務系統的郵件,這樣電子郵件系統相當于郵局) 。現在主要電子郵件服務系統主要有下面幾種:

基于Postfix/Qmail的郵件系統。例如,雅虎郵箱基于Qmail系統

微軟Exchange 郵件系統

IBM Lotus Domino郵件系統

Scalix郵件系統

Zimbra郵件系統

MDeamon郵件系統

二、.Net 平臺對郵件發送功能的支持

在.NET類庫中,在System.Net.Mail命名空間下定義了對郵件處理的類,這樣使郵件的發送更加方便(這些類也就是對SMTP協議的封裝,使我們更好地區編程,只需要使用類中的方法和屬性等去完成郵件的發送,避免寫復雜的SMTP協議的命令),下面是一張在System.Net.Mail命名空間下對郵件發送的支持的類截圖:

從圖片中類的名字中也可以看出每個類的作用的,在這里我就不一個介紹的, 大家可以參考MSDN去看每個類的使用,并且我在后面程序的實現部分也會有詳細的注釋去介紹程序中使用到類的使用。從圖中還可以i看出一點——就是只有SMTP的字樣,卻沒有POP3這樣的字樣的,這說明.Net類庫本身中并沒有提供對POP3協議的封裝類,但是我們可以使用Jmail組件來完成從POP3服務器中收取郵件的功能,具體的使用將在后面的郵件收發器程序中郵件的接收部分介紹的。

三、郵件收發器程序的實現

3.1 郵件發送功能的實現

3.1.1 SMTP協議

SMTP 協議是用于電子郵件的傳輸的協議,電子郵件是通過SMTP服務器進行發送的,SMTP服務器的默認端口為25,通常發送郵件有兩種方式——一種是不使用客戶端認證,即客戶端可以使用匿名發送郵件(這種方式叫做SMTP);另一種是客戶端必須提供用戶名和密碼認證(這種方式叫做ESMTP,Extended SMTP)目前大部分郵件服務器采用用戶名和密碼認證的方式。

客戶端發送郵件過程為——先通過客戶端軟件(本程序中的郵件收發器)將郵件發送到SMTP服務器,然后再由SMTP服務器發送到目標SMTP服務器。下面介紹SMTP協議的內容:

SMTP協議總共定義了14個命令,命令由命令碼和氣候的參數域組成, 不區別大小寫的(通過前面專題的講述可以得出各個協議的命令組成都差不多的),下面就簡單介紹下5個常用的命令碼

電子郵件由信封、首部、正文和結束符號4部分組成,下面就具體介紹下這4個部分的內容:

1. 信封

信封包括發信人的郵件地址和接收人的郵件地址,具體對應兩條SMTP命令——Mail from: mytest1989@sina.cn(發信人的地址)和Rcpt to:  794170314@qq.com

2. 首部

首部中常用的命令有:

Subject:<郵件主題>——表示郵件的主題

Date:<時間>——表示發郵件的時間

reply-to:<郵件地址>——表示郵件的回復地址

Content-Type:<郵件類型>——表示郵件包含文本、HTML超文本和附件的類型。

X-Priority:<郵件優先級>——表示郵件發送的優先級,優先級為3表示為普通郵件;如 X-Priority:3

3. 正文

正文當然指的就是郵件的內容了, 用Data命令指定,首部以一個空行結束,下面就是正文部分

4. 結束符號

郵件以“."結束,

接收方收到SMTP命令之后,會給出一個響應碼,每個命令都只有一個響應碼,SMTP響應碼也是由3位數字組成,后面附加一些文本信息,響應信息的格式為:

響應碼<空格>文本信息<回車換行>

客戶端發出一條命令后,服務器端返回一個響應,發送者在發送下一條命令前必須等待服務器的響應,成功接收到響應碼后才繼續發送命令。

附:SMTP常用的響應碼:

 

3.1.2 郵件的發送過程

第一步:客戶端與服務器建立連接(該步中客戶端首先發送EHLO local 連接命令,服務器如果返回“220”響應碼表示服務器準備就緒了,客戶端再繼續發送“Auto login”命令,請求登錄,服務器收到命令后返回“334”響應碼,表示要輸入用戶名,之后客戶端發送用戶名命令,等到響應后再發送密碼命令,具體在程序的實現中也會有注釋。)

第二步:客戶端發送郵件的信封

第三步:開始發送郵件數據,(包括郵件首部,正文和結束符號,注:結束符號要單獨占一行,表示郵件發送結束)

第四步: 客戶端與服務器斷開連接。

3.1.3 發送功能的實現代碼

相信有了上面的理論解釋郵件發送的過程后,實現郵件發送的功能并不難的,并且.net類庫中SMTPClient類幫我們封裝了SMTP協議,使得我們實現郵件發送功能就不要記住那些具體的命令了, 只需要使用該類中提供的方法來完成郵件的發送(當然你也可以通過發送命令的方式實現,SMTPClient類的方法也是幫我們完成發送命令功能而已的),下面是郵件發送功能的核心代碼:

  1. View Code   
  2.  #region 郵件發送功能代碼  
  3.          // 添加附件  
  4.          private void btnAddFile_Click(object sender, EventArgs e)  
  5.          {  
  6.              OpenFileDialog openFileDialog = new OpenFileDialog();  
  7.              openFileDialog.CheckFileExists = true;  
  8.              // 只接受有效的文件名  
  9.              openFileDialog.ValidateNames = true;  
  10.              // 允許一次選擇多個文件作為附件  
  11.              openFileDialog.Multiselect = true;  
  12.              openFileDialog.Filter = "所有文件(*.*)|*.*";  
  13.              if (openFileDialog.ShowDialog() != DialogResult.OK)  
  14.              {  
  15.                  return;  
  16.              }  
  17.              if (openFileDialog.FileNames.Length > 0)  
  18.              {  
  19.                  // 因為這里允許選擇多個文件,所以這里用AddRange而沒有用Add方法  
  20.                  cmbAttachment.Items.AddRange(openFileDialog.FileNames);  
  21.              }  
  22.          }  
  23.    
  24.          // 刪除附件  
  25.          private void btnDeleteFile_Click(object sender, EventArgs e)  
  26.          {  
  27.              int index = cmbAttachment.SelectedIndex;  
  28.              if (index == -1)  
  29.              {  
  30.                  MessageBox.Show("請選擇要刪除的附件!""提示", MessageBoxButtons.OK, MessageBoxIcon.Information);  
  31.                  return;  
  32.              }  
  33.              else 
  34.              {  
  35.                  cmbAttachment.Items.RemoveAt(index);  
  36.              }  
  37.          }  
  38.    
  39.          // 發送郵件  
  40.          private void btnSend_Click(object sender, EventArgs e)  
  41.          {  
  42.              this.Cursor = Cursors.WaitCursor;  
  43.              // 實例化一個發送的郵件  
  44.              // 相當于與現實生活中先寫信,程序中把信(郵件)抽象為郵件類了  
  45.              MailMessage mailMessage = new MailMessage();  
  46.              // 指明郵件發送的地址,主題,內容等信息  
  47.              // 發信人的地址為登錄收發器的地址,這個收發器相當于我們平時Web版的郵箱或者是OutLook中配置的郵箱  
  48.              mailMessage.From = new MailAddress(tbxUserMail.Text);  
  49.              mailMessage.To.Add(txbSendTo.Text);  
  50.              mailMessage.Subject = txbSubject.Text;  
  51.              mailMessage.SubjectEncoding = Encoding.Default;  
  52.              mailMessage.Body = richtbxBody.Text;  
  53.              mailMessage.BodyEncoding = Encoding.Default;  
  54.              // 設置郵件正文不是Html格式的內容  
  55.              mailMessage.IsBodyHtml = false;  
  56.              // 設置郵件的優先級為普通優先級  
  57.              mailMessage.Priority = MailPriority.Normal;  
  58.              //mailMessage.ReplyTo = new MailAddress(tbxUserMail.Text);  
  59.    
  60.              // 封裝發送的附件  
  61.              System.Net.Mail.Attachment attachment = null;  
  62.              if (cmbAttachment.Items.Count > 0)  
  63.              {  
  64.                  for (int i = 0; i < cmbAttachment.Items.Count; i++)  
  65.                  {  
  66.                      string fileNamePath = cmbAttachment.Items[i].ToString();  
  67.                      string extName = Path.GetExtension(fileNamePath).ToLower();  
  68.                      if (extName == ".rar" || extName == ".zip")  
  69.                      {  
  70.                          attachment = new System.Net.Mail.Attachment(fileNamePath, MediaTypeNames.Application.Zip);  
  71.                      }  
  72.                      else 
  73.                      {  
  74.                          attachment = new System.Net.Mail.Attachment(fileNamePath,MediaTypeNames.Application.Octet);  
  75.                      }  
  76.    
  77.                      // 表示MIMEContent-Disposition標頭信息  
  78.                      // 對于ContentDisposition具體類的解釋大家可以參考MSDN  
  79.                      // 這里我就不重復貼出來了,給個地址: http://msdn.microsoft.com/zh-cn/library/System.Net.Mime.ContentDisposition.aspx (著重看備注部分)  
  80.                      ContentDisposition cd = attachment.ContentDisposition;  
  81.                      cd.CreationDate = File.GetCreationTime(fileNamePath);  
  82.                      cd.ModificationDate = File.GetLastWriteTime(fileNamePath);  
  83.                      cd.ReadDate = File.GetLastAccessTime(fileNamePath);  
  84.                      // 把附件對象加入到郵件附件集合中  
  85.                      mailMessage.Attachments.Add(attachment);  
  86.                  }  
  87.              }  
  88.    
  89.              // 發送寫好的郵件  
  90.              try 
  91.              {  
  92.                  // SmtpClient類用于將郵件發送到SMTP服務器  
  93.                  // 該類封裝了SMTP協議的實現,  
  94.                  // 通過該類可以簡化發送郵件的過程,只需要調用該類的Send方法就可以發送郵件到SMTP服務器了。  
  95.                  smtpClient.Send(mailMessage);  
  96.                  MessageBox.Show("郵件發送成功!""提示", MessageBoxButtons.OK, MessageBoxIcon.Information);  
  97.    
  98.              }  
  99.              catch(SmtpException smtpError)  
  100.              {  
  101.                  MessageBox.Show("郵件發送失敗:[" + smtpError.StatusCode + "];["   
  102.                      + smtpError.Message+"];\r\n["+smtpError.StackTrace+"]." 
  103.                      ,"錯誤",MessageBoxButtons.RetryCancel,MessageBoxIcon.Error);  
  104.              }  
  105.              finally 
  106.              {  
  107.                  mailMessage.Dispose();  
  108.                  this.Cursor = Cursors.Default;  
  109.              }  
  110.          }  
  111.    
  112.          #endregion 

3.2 郵件接收功能的實現

3.2.1 POP3協議

前面介紹了郵件的發送,當然接收者需要登錄郵箱來查看收到的郵件了,此時就必有有一個協議去讀取服務器上郵件,POP3就是這樣的一個協議。還有兩外一種協議也是用來接收郵件的——IMAP協議,它與POP3協議區別有:

1. IMAP使用的端口號是143而POP3郵件服務器通過監聽110端口來提供POP3服務;

2 . IMAP 允許客戶端在郵件服務器上建立文件夾來保持郵件,而不用把郵件下載到本地。而POP3需要把郵件下載到本地。

和SMTP協議一樣,客戶端要通過POP3協議從POP3服務器上獲取郵件,也需要先與POP3服務器建立TCP連接,等待服務器向客戶端發送確認信息表明連接成功時,客戶端才可以繼續發送命令給服務器來獲取郵件,在POP3協議中,規定的命令也是幾十條的,每條命令由命令和參數兩部分組成,都是以回車換行結束,并且命令和參數之間由空格分隔,命令通常也是由3-4個字母組成,參數最多可以為40個字符的長度,而服務器的響應信息是由一個狀態碼和可能附加信息的字符組成,所有的響應信息也是以回車換行結束的。狀態碼和其他協議定義的狀態碼有點不一樣,POP3服務器響應的狀態碼有兩種——“+OK”(確定)和"-ERR"(失敗)。這樣客戶端可以通過檢查響應的狀態碼所包含的字符來判斷服務器是否響應客戶端發送的命令,即響應信息中包含“+OK”表示成功響應,包含“-ERR”表示服務器未響應。同時在程序的實現中大家可以通過Debug來查看響應消息的組成,這樣可以加深理解。

3.2.2 郵件接收的過程

客戶端從服務器接收郵件的過程主要經歷3個狀態:授權狀態、操作狀態和更新狀態

(1)授權狀態——客戶端發送與POP3服務器的TCP連接請求,服務器接收后發送一個響應確認信息之后,此時客戶端需要發送正確的用戶名和密碼進行確認,因為在郵件服務器上有很多用戶郵箱,只有提供正確的用戶名和密碼才有權限訪問自己的郵箱,就像現實生活中我們郵箱的鑰匙一樣的。

發送用戶名命令: USER mytest1989@sina.cn

發送密碼命令: PASS ******(這兩個命令都在代碼中有給出的,大家可以參考代碼來理解郵件的接收過程)

(2) 操作狀態——如果客戶端提供了正確的用戶名和密碼,則授權狀態也就通過了,就相當于打開了在服務器上自己的郵箱,現在用戶就有權限進去下載,查看和刪除郵件等操作的,然后在現實生活中的取郵件和刪除郵件都很簡單(只要打開了郵箱門,用手去拿就可以了),然后在網絡應用上,這些操作都需要發送POP3命令給服務器,服務器接收到命令后再給出響應。操作中常用的命令有:

STAT 命令——該命令從服務器中獲取郵件總數和總字節數,服務器響應命令返回郵件總數和總字節數。如:

  1. 客戶端發送POP3命令: STAT   
  2. 服務器響應命令: +OK 2 1340<BR>服務器響應命令: 

LIST 命令——該命令從服務器中獲得郵件列表和大小,服務器響應命令返回列出郵件列表和大小。如: 

  1. 客戶端發送POP3命令:LIST   
  2. 服務器響應命令: +OK 2 message(1430 octect)   
  3. 服務器響應命令:1    700   
  4. 服務器響應命令:2    730   
  5. 服務器響應命令:<一個空行> 

RETR 命令—— 該命令從服務器中獲得一個郵件,格式為 RETR <郵件編號>如:

  1. 客戶端發送POP3命令:RETR 1   
  2. 服務器響應命令: 700 octets   
  3. 服務器響應命令:<郵件頭和內容>   
  4. 服務器響應命令: <空行> 

DELETE 命令——該命令告訴服務器將郵件標記為刪除。(此時只是邏輯刪除) 

(3)更新狀態——客戶端發送QUIT命令后,此時就進入更新狀態,POP3服務器釋放在操作狀態中取得的資源,并將邏輯刪除的郵件進行物理刪除,然后關閉與客戶端的TCP連接。這樣整個郵件處理的過程就結束了。

3.2.3 接收功能的實現代碼

有了前面接收郵件過程的介紹,再參考代碼的實現,相信大家可以更好的理解客戶端從POP3服務器中獲取郵件的過程的,由于.net類庫并沒有幫我們封裝POP3協議的實現類,要實現郵件的獲取可以采用發送命令的方式,也可以使用Jmail組件,這個組件其實就是POP3協議的封裝類,既然微軟沒有幫我們做,其他公司幫我們做好后來幫助我們簡單的實現郵件的接收的一個類庫罷了。然后在使用這個組件的過程中出現了好幾個問題的,在源碼中我都解釋,大家可以下載源代碼后查看的。

實現郵件接收的核心代碼如下:

  1. // 登錄郵箱(這里是本程序——郵件收發器)  
  2.        private void btnLogin_Click_1(object sender, EventArgs e)  
  3.        {  
  4.            // 與POP3服務器建立TCP連接  
  5.            // 建立連接后把服務器上的郵件下載到本地  
  6.            // 設置當前界面的光標為等待光標(就是我們看到的一個動的圓形)  
  7.            Cursor.Current = Cursors.WaitCursor;  
  8.  
  9.            lsttbxStatus.Items.Clear();  
  10.            try 
  11.            {  
  12.                // POP3服務器通過監聽TCP110端口來提供POP3服務的  
  13.                // 向POP3服務器發出tcp請求  
  14.                tcpClient = new TcpClient(tbxPOP3Server.Text, 110);  
  15.                lsttbxStatus.Items.Add("正在連接...");  
  16.            }  
  17.            catch 
  18.            {  
  19.                MessageBox.Show("連接失敗""錯誤", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);  
  20.                lsttbxStatus.Items.Add("連接失敗!");  
  21.                return;  
  22.            }  
  23.  
  24.            // 連接成功的情況  
  25.            networkStream = tcpClient.GetStream();  
  26.            streamReader = new StreamReader(networkStream, Encoding.Default);  
  27.            streamWriter = new StreamWriter(networkStream, Encoding.Default);  
  28.            streamWriter.AutoFlush = true;  
  29.            string str;  
  30.            // 讀取服務器返回的響應連接信息  
  31.            str = GetResponse();  
  32.            if (CheckResponse(str) == false)  
  33.            {  
  34.                lsttbxStatus.Items.Add("服務器拒接了連接請求");  
  35.                return;  
  36.            }  
  37.            // 如果服務器接收請求  
  38.            // 向服務器發送憑證——用戶名和密碼  
  39.  
  40.            // 向服務器發送用戶名,請求確認  
  41.            lsttbxStatus.Items.Add("核實用戶名階段...");  
  42.            SendToServer("USER " + tbxUserMail.Text);  
  43.            str = GetResponse();  
  44.            if (CheckResponse(str) == false)  
  45.            {  
  46.                lsttbxStatus.Items.Add("用戶名錯誤.");  
  47.                return;  
  48.            }  
  49.  
  50.            // 用戶名審核通過后再發送密碼等待確認  
  51.            // 向服務器發送密碼,請求確認  
  52.            SendToServer("PASS "+txbPassword.Text);  
  53.            str = GetResponse();  
  54.            if (CheckResponse(str) == false)  
  55.            {  
  56.                lsttbxStatus.Items.Add("密碼錯誤!");  
  57.                return;  
  58.            }  
  59.  
  60.            lsttbxStatus.Items.Add("身份驗證成功,可以開始會話");  
  61.            // 向服務器發送LIST 命令,請求獲得郵件列表和大小  
  62.            lsttbxStatus.Items.Add("獲取郵件....");  
  63.            SendToServer("LIST");  
  64.            str = GetResponse();  
  65.            if (CheckResponse(str) == false)  
  66.            {  
  67.                lsttbxStatus.Items.Add("獲取郵件列表失敗");  
  68.                return;  
  69.            }  
  70.  
  71.            lsttbxStatus.Items.Add("郵件獲取成功");  
  72.  
  73.            // 窗口控件控制  
  74.            tabControlMyMailbox.Enabled = true;  
  75.            btnReadMail.Enabled = false;  
  76.            btnDownLoad.Enabled = false;  
  77.            btnDeleteMail.Enabled = false;  
  78.  
  79.            // 登陸成功后實例化郵件發送對象,以便后面完成發送郵件的操作  
  80.            // 實例化郵件發送類(SmtpClient)對象  
  81.            if (smtpClient == null)  
  82.            {  
  83.                smtpClient = new SmtpClient();  
  84.                smtpClient.Host = tbxSmtpServer.Text;  
  85.                smtpClient.Port = 25;  
  86.                      
  87.                // 不使用默認憑證,即需要認證登陸  
  88.                smtpClient.UseDefaultCredentials = false;  
  89.                smtpClient.Credentials = new NetworkCredential(tbxUserMail.Text, txbPassword.Text);  
  90.                smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;  
  91.            }  
  92.  
  93.            // 登陸成功后,自動接收新郵件  
  94.            // 開始接收郵件  
  95.            try 
  96.            {  
  97.                btnRefreshMailList.PerformClick();  
  98.            }  
  99.            catch 
  100.            {  
  101.                MessageBox.Show("讀取郵件列表失敗!""錯誤", MessageBoxButtons.RetryCancel, MessageBoxIcon.Error);  
  102.            }  
  103.  
  104.            lsttbxStatus.Items.Add("登陸成功!");  
  105.            lsttbxStatus.TopIndex = lsttbxStatus.Items.Count - 1;  
  106.            Cursor.Current = Cursors.Default;  
  107.  
  108.            // 窗口控件控制  
  109.            richtbxMailContentReview.Enabled = true;  
  110.            tbxUserMail.Enabled = false;  
  111.            txbPassword.Enabled = false;  
  112.            btnLogin.Enabled = false;  
  113.            btnLogout.Enabled = true;  
  114.            tbxSmtpServer.Enabled = false;  
  115.            tbxPOP3Server.Enabled = false;  
  116.            btnReadMail.Enabled = true;  
  117.            btnDownLoad.Enabled = true;  
  118.            btnDeleteMail.Enabled = true;  
  119.            tabControlMyMailbox.Focus();  
  120.        }  
  121.  
  122.        #region 處理與POP3服務器交互事件  
  123.        // 獲取服務器響應的信息  
  124.        private string GetResponse()  
  125.        {  
  126.            string str = null;  
  127.            try 
  128.            {  
  129.                str = streamReader.ReadLine();  
  130.                if (str == null)  
  131.                {  
  132.                    lsttbxStatus.Items.Add("連接失敗——服務器沒有響應");  
  133.                }  
  134.                else 
  135.                {  
  136.                    lsttbxStatus.Items.Add("收到:[" + str + "]");  
  137.                    if (str.StartsWith("-ERR"))  
  138.                    {  
  139.                        str = null;  
  140.                    }  
  141.                }  
  142.            }  
  143.            catch(Exception err)  
  144.            {  
  145.                lsttbxStatus.Items.Add("連接失敗:[" + err.Message + "]");  
  146.            }  
  147.  
  148.            return str;  
  149.        }  
  150.  
  151.        // 檢查響應信息  
  152.        private bool CheckResponse(string responseString)  
  153.        {  
  154.            if (responseString == null)  
  155.            {  
  156.                return false;  
  157.            }  
  158.            else 
  159.            {  
  160.                if (responseString.StartsWith("+OK"))  
  161.                {  
  162.                    return true;  
  163.                }  
  164.                else 
  165.                {  
  166.                    return false;  
  167.                }  
  168.            }  
  169.        }  
  170.  
  171.        // 向服務器發送命令  
  172.        private bool SendToServer(string str)  
  173.        {  
  174.            try 
  175.            {  
  176.                // 這里必須使用WriteLine方法的,因為POP3協議中定義的命令是以回車換行結束的  
  177.                // 如果客戶端發送的命令沒有以回車換行結束,POP3服務器就不能識別,也就不能響應客戶端的請求了  
  178.                // 如果想用Write方法,則str輸入的參數字符中必須包含“\r\n”,也就是回車換行字符串。  
  179.                streamWriter.WriteLine(str);  
  180.                streamWriter.Flush();  
  181.                lsttbxStatus.Items.Add("發送:[" + str + "]");  
  182.                return true;  
  183.            }  
  184.            catch(Exception ex)  
  185.            {  
  186.                lsttbxStatus.Items.Add("發送失敗:[" + ex.Message + "]");  
  187.                return false;  
  188.            }  
  189.        }  
  190.        #endregion 

3.3 程序運行結果演示

首先輸入郵箱名和密碼登錄到POP3服務器來獲取郵件列表的演示:

然后在郵件列表中選中一個郵件進行閱讀,然后進行回復郵件的操作演示(郵件的發送都可以附加附件發送出去):

閱讀郵件的界面:

回復郵件的界面:

同時點擊發送按鈕后,就可以把郵件發送到sina的SMTP服務器上,再由新浪的SMTP服務器轉發到QQ的SMTP服務器,QQ的POP3服務器中QQ的SMTP服務器獲取收到的郵件,當QQ用戶輸入正確的郵箱名和密碼后就可以從QQ的POP3服務器上獲取收到的郵件。

點擊發送按鈕后成功發送郵件的圖片:

四、總結

介紹到這里,本專題的內容就已經介紹完了,希望通過本專題可以讓大家明白郵件發送和接收的原理,并且可以自定義一個簡單郵件收發器的功能的,在后面一專題將介紹FTP協議(文件傳輸協議),并實現一個簡單的文件上傳和下載的程序。

源代碼下載地址: http://files.cnblogs.com/zhili/MailSendAndReceive.zip 

原文鏈接:http://www.cnblogs.com/zhili/archive/2012/09/24/MailSend_POP3_SMTP.html

【編輯推薦】

  1. C#網絡編程系列一:網絡協議簡介
  2. C#網絡編程系列二:HTTP協議詳解
  3. C#網絡編程系列三:自定義Web服務器
  4. C#網絡編程系列四:自定義Web瀏覽器
  5. C#網絡編程系列五:TCP編程
  6. C#網絡編程系列六:UDP編程
  7. C#網絡編程系列七:UDP編程補充
  8. C#網絡編程系列八:P2P編程
  9. C#網絡編程系列九:類似QQ的即時通信程序
責任編輯:張偉 來源: Learning hard的博客
相關推薦

2012-09-24 15:13:50

C#網絡協議TCP

2012-09-24 15:35:24

C#網絡協議UDP

2012-09-25 11:28:38

C#網絡協議UDP

2012-09-24 14:03:58

C#網絡協議C

2023-12-27 15:31:55

2023-09-20 14:35:43

2011-06-16 09:15:24

光纖收發器交換機環網

2010-07-09 11:15:55

Visual C# U

2009-08-31 17:53:20

C#實現索引器

2012-09-24 14:09:31

C#網絡協議C

2012-09-25 13:47:43

C#網絡協議P2P

2009-07-07 18:40:00

收發器連接

2012-09-24 14:43:51

C#網絡協議C

2012-09-24 14:31:55

C#網絡協議C

2024-03-04 18:49:59

反射C#開發

2009-09-07 14:29:47

C# Socket編程C# Socket

2009-07-11 17:10:24

WiMAX收發系統接收

2009-09-07 15:27:04

C# MessageB

2009-08-13 10:15:50

C#讀取Excel

2009-08-06 10:55:46

C#代碼解釋器
點贊
收藏

51CTO技術棧公眾號

一区二区三区四区五区精品视频| 色网在线免费观看| 美女在线视频一区| 色哟哟网站入口亚洲精品| 国产黄色特级片| 精品国产av鲁一鲁一区| 欧美日韩一视频区二区| 亚洲第一av在线| 欧美日韩黄色一级片| 六月婷婷综合网| 亚洲一区二区毛片| 伊人久久综合97精品| 国产第一页视频| 黄色av免费在线| 成人永久aaa| 青青久久aⅴ北条麻妃| 国产婷婷在线观看| 吞精囗交69激情欧美| 自拍偷在线精品自拍偷无码专区| 成人18视频| 色屁屁影院www国产高清麻豆| 日韩欧美国产精品综合嫩v| 欧美男人的天堂一二区| 丁香六月激情婷婷| 狠狠综合久久av一区二区| 久久激情一区| 久久6精品影院| 无码国产69精品久久久久同性| 91超碰免费在线| 国产精品久久久久久亚洲伦 | 色噜噜色狠狠狠狠狠综合色一| 国产乱人乱偷精品视频a人人澡| 伊人久久婷婷| 日韩在线观看免费高清完整版| 性欧美在线视频| av2020不卡| 欧美国产欧美综合| 久久久久se| 国产成人麻豆精品午夜在线| 日本成人中文字幕| 国外成人免费在线播放| 精品伦精品一区二区三区视频密桃| 136福利精品导航| 欧美日韩国产色站一区二区三区| 亚洲午夜精品一区二区| 少妇喷水在线观看| 激情五月播播久久久精品| 人妖精品videosex性欧美| 一级片一级片一级片| 国偷自产视频一区二区久| 91久久精品国产91性色tv| 成人在线免费观看网址| 国产v在线观看| 美女在线观看视频一区二区| 欧美激情成人在线视频| 欧美第一页在线观看| 秋霞欧美视频| 亚洲男人7777| 韩国三级hd中文字幕有哪些| 欧美久久久网站| 在线一区二区视频| 欧美一级黄色片视频| 91丝袜在线| 亚洲黄色尤物视频| 国产高清免费在线| 精品国产丝袜高跟鞋| 国产精品日日摸夜夜摸av| 日韩欧美精品在线不卡| 国产尤物视频在线| 国产午夜精品一区二区| 日韩影片在线播放| 国产在线资源| 国产欧美va欧美不卡在线| 日韩.欧美.亚洲| 美国成人毛片| 久久夜色精品国产欧美乱极品| 精品一区日韩成人| 嫩草研究院在线| 久久精品亚洲麻豆av一区二区| 99国产超薄肉色丝袜交足的后果| 中文无码av一区二区三区| 香蕉久久国产| 欧美中文在线字幕| 亚洲s码欧洲m码国产av| 日韩国产在线一| 国产精品直播网红| 一区二区视频网站| 日产国产高清一区二区三区 | 久久99亚洲网美利坚合众国| 亚洲国产精品99久久久久久久久 | 国产女18毛片多18精品| 国产在线精品不卡| a级国产乱理论片在线观看99| 免费a视频在线观看| 国产91精品精华液一区二区三区 | 国产乱人伦偷精品视频不卡| 国产精品久久久一区二区三区| 欧美视频在线观看一区二区三区| 99久久精品免费看| 欧美日韩一区二区三| 亚洲搞黄视频| 亚洲一区免费在线观看| 国产一区二区三区小说| 欧美xx视频| 欧美日韩不卡视频| 稀缺小u女呦精品呦| 欧美丝袜足交| 在线日韩欧美视频| 高h视频免费观看| 一区二区精品| 成人免费福利在线| 欧美一级淫片aaaaaa| 久久综合色综合88| 一区二区在线观| www555久久| 色婷婷久久99综合精品jk白丝| 国产乱码一区二区三区四区| 美女一区2区| 中文字幕视频一区二区在线有码| 精品少妇久久久| 日韩精品电影一区亚洲| 成人免费观看网站| 国产片在线观看| 亚洲成av人在线观看| 久久久精品麻豆| 澳门久久精品| 国产一区二区三区视频在线观看 | 天堂午夜影视日韩欧美一区二区| 成人h片在线播放免费网站| 日本韩国免费观看| 亚洲三级电影网站| 日韩一级在线免费观看| 成人福利免费在线观看| 一区二区三区高清国产| 久久免费小视频| 捆绑调教美女网站视频一区| 国产精品三区四区| 黄色免费网站在线观看| 欧美综合亚洲图片综合区| 亚洲国产精品狼友在线观看| 免费毛片在线不卡| 国外成人免费在线播放| 99这里有精品视频| 国产精品日韩精品欧美在线 | 免费在线播放第一区高清av| 成人夜晚看av| 北岛玲一区二区三区| 欧美日韩一区二区三区| wwwxxx色| 亚洲成人二区| 国产精品入口尤物| 黄色av网站在线| 亚洲国产va精品久久久不卡综合| 国产九九九视频| 999国产精品| 欧美一区二区三区艳史| www.色日本| 亚洲色图第一区| 免费网站在线观看黄| 九九久久婷婷| 久久久久五月天| 亚洲精品国产片| 亚洲啪啪综合av一区二区三区| 国产免费999| 国产精品免费99久久久| 欧美综合一区第一页| 四虎影视精品成人| 色综合天天做天天爱| 久久精品女同亚洲女同13| 日韩在线欧美| 国产成人97精品免费看片| 欧美女优在线| 欧美日韩免费网站| 中文字幕一区二区人妻在线不卡| 伊人蜜桃色噜噜激情综合| 国产精品久久精品国产| gogo在线高清视频| 欧美电影免费观看完整版| 欧美激情精品久久| 白白色 亚洲乱淫| 69堂免费视频| 国产videos久久| 国产99久久精品一区二区| 国产精品99999| 欧洲一区二区av| 天天操天天摸天天舔| 国产一区二区三区观看| 天天操天天干天天玩| 日韩电影免费观看高清完整版| 国产视频精品va久久久久久| 亚洲无码精品一区二区三区| 国产精品久久久久国产精品日日| 国产精品人人妻人人爽人人牛| 成人一区不卡| 国产精品久久国产精品99gif| h视频在线观看免费| 欧美精品在线一区二区三区| 国产又黄又爽又无遮挡| 99麻豆久久久国产精品免费优播| 国产成人综合一区| 在线精品国产| 欧美日韩一区二区视频在线| yw.尤物在线精品视频| 久久这里只有精品视频首页| 国产夫妻在线观看| 欧美色视频日本高清在线观看| 国产真实乱子伦| 999成人精品视频线3| 成人高清在线观看| av有声小说一区二区三区| 这里只有精品在线播放| 国产精品人妻一区二区三区| 狠狠色狠色综合曰曰| 亚洲欧洲综合网| 高清成人免费视频| 日韩大片一区二区| 中文字幕亚洲综合久久五月天色无吗''| 极品校花啪啪激情久久| 黄色成人在线观看网站| 久久免费成人精品视频| 中文字幕日本在线观看| 亚洲精品99999| 欧美激情一区二区三区免费观看| 亚洲视频精选在线| 中文字幕人妻一区二区三区在线视频| 国产精品一品二品| 成人黄色片视频| 黄色欧美日韩| 日韩精品成人一区二区在线观看| 电影中文字幕一区二区| 国产成人短视频| av男人的天堂在线观看| 一个人看的www久久| 天堂在线中文网| 欧美性色综合网| 久久狠狠高潮亚洲精品| 一区二区三区免费在线观看| 无遮挡aaaaa大片免费看| 国产自产高清不卡| 免费观看精品视频| 国内精品美女在线观看 | 国产成人生活片| 欧美影院三区| 成人欧美一区二区三区视频 | 在线免费一级片| 一本大道久久a久久综合婷婷| 国产一级做a爰片在线看免费| www成人在线观看| 亚洲视频在线播放免费| 丰满少妇久久久久久久| 久久精品在线免费视频| 国产亚洲一区| 日韩.欧美.亚洲| 奇米影视亚洲| 中文字幕一区二区三区在线乱码 | 91动漫在线看| 亚洲少妇自拍| 毛片av免费在线观看| 青青草成人在线观看| 老司机午夜性大片| 国产乱人伦偷精品视频免下载| 久久久久久久久久影视| fc2成人免费人成在线观看播放 | 中文字幕va一区二区三区| 性欧美13一14内谢| 国产精品色呦呦| 日本精品在线观看视频| 亚洲欧美在线视频观看| 任你操精品视频| 亚洲午夜三级在线| 天堂网免费视频| 91精品国产一区二区| 欧美自拍偷拍一区二区| 亚洲人成电影在线| 麻豆网站视频在线观看| 久久99青青精品免费观看| 玖玖在线播放| 国产欧美精品va在线观看| 精品一区二区三区在线观看视频| 91日本视频在线| 99ri日韩精品视频| 久久艳妇乳肉豪妇荡乳av| 日本女优一区| 国产成人三级视频| 成人av动漫在线观看| 穿情趣内衣被c到高潮视频| 亚洲视频大全| 日本黄色的视频| av中文字幕不卡| 2014亚洲天堂| 亚洲午夜免费视频| 中文字幕av在线免费观看| 日韩精品一区二区三区三区免费| 国产在线色视频| 欧美国产在线电影| 视频在线日韩| 国产精品一区而去| 久久一区二区中文字幕| 国产v片免费观看| 久久99久久99精品免视看婷婷| 人妻激情偷乱频一区二区三区| 中文字幕乱码亚洲精品一区| 日本熟妇毛耸耸xxxxxx| 欧美日韩性生活| 日本一区二区三区在线观看视频| 久久香蕉国产线看观看网| 国内在线免费视频| 日韩免费av在线| 果冻天美麻豆一区二区国产| 影音先锋欧美在线| 亚洲国产片色| 亚洲一区精品视频在线观看| 久久久另类综合| 日韩久久久久久久久| 717成人午夜免费福利电影| 男人久久精品| 97精品久久久中文字幕免费| 欧美区一区二区| 一区二区三区电影| 亚洲一区国产一区| 国偷自产av一区二区三区麻豆| 久久综合精品国产一区二区三区| 久久97人妻无码一区二区三区| 欧美另类videos死尸| 青青草在线播放| 亚洲最大中文字幕| 少妇淫片在线影院| 国产精品久久久久秋霞鲁丝| 神马香蕉久久| 国产精品网站免费| 成人免费观看男女羞羞视频| 破处女黄色一级片| 欧美日韩成人一区| 在线免费观看黄色网址| 国产精品老牛影院在线观看| 亚州av日韩av| 18岁网站在线观看| 成人av电影免费在线播放| 欧美精品乱码视频一二专区| 欧美在线短视频| 国产午夜在线视频| 国产91色在线免费| 亚洲最大在线| 情侣黄网站免费看| 国产亚洲人成网站| 日本熟女毛茸茸| 国产一区二区三区在线| 亚洲国产尤物| 裸模一区二区三区免费| 免费视频久久| 91激情视频在线观看| 亚洲国产成人自拍| 亚洲天堂网视频| 亚洲日本欧美中文幕| 69堂免费精品视频在线播放| 亚洲精品成人自拍| 寂寞少妇一区二区三区| 91av手机在线| 欧美一区二区福利视频| 久久av色综合| 欧美视频观看一区| 麻豆成人久久精品二区三区红| 亚洲精品国产精品国自产网站| 欧美日韩国产中文| 欧美xxxxhdvideosex| 国精产品99永久一区一区| 激情综合激情| 无码一区二区精品| 色94色欧美sute亚洲13| 日本中文字幕在线观看| 91蜜桃网站免费观看| 99精品热视频只有精品10| 中文字幕一二三四区| 欧美日韩精品一区二区在线播放| 黄网页在线观看| 福利精品视频| 久久av一区| 欧美日韩色视频| 亚洲成人精品av| 一区在线影院| 人妻av无码专区| 久久久久久97三级| 99久久免费国产精精品| 91国产视频在线播放| 亚洲国产国产| 亚洲色图久久久| 一区二区三区中文字幕电影| 色视频在线看| 国产97在线|日韩| 欧美日韩1区2区3区| 无码国产69精品久久久久同性| 欧美一区二区高清| 黄色污污视频在线观看| 污视频在线免费观看一区二区三区| 国产高清在线精品| 日韩精品成人免费观看视频| 草民午夜欧美限制a级福利片| 亚洲毛片免费看| 日本泡妞xxxx免费视频软件| 欧美日韩一区二区三区不卡|