C#接收電子郵件


/////////////////////////////////////////////

// 類名:Pop3         //

// 功能:接收電子郵件          //

/////////////////////////////////////////////

using System;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.IO;


namespace ZTSX.Email
{
 /// <summary>
 /// Pop3 的摘要說明。
 /// </summary>
 public class Pop3
 {
  private string mstrHost     = null;  //主機名稱或IP地址
  private int mintPort     = 110;  //主機的端口號(默認為110)
  private TcpClient mtcpClient   = null;  //客戶端
  private NetworkStream mnetStream  = null;  //網絡基礎數據流
  private StreamReader m_stmReader  = null;  //讀取字節流
  private string mstrStatMessage   = null;  //執行STAT命令后得到的消息(從中得到郵件數)

  /// <summary>
  /// 構造函數
  /// </summary>
  /// <remarks>一個郵件接收對象</remarks>
  public Pop3()
  {
  }

  /// <summary>
  /// 構造函數
  /// </summary>
  /// <param name="host">主機名稱或IP地址</param>
  public Pop3(string host)
  {
   mstrHost = host;
  }

  /// <summary>
  /// 構造函數
  /// </summary>
  /// <param name="host">主機名稱或IP地址</param>
  /// <param name="port">主機的端口號</param>
  /// <remarks>一個郵件接收對象</remarks>
  public Pop3(string host,int port)
  {
   mstrHost = host;
   mintPort = port;
  }

  #region 屬性

  /// <summary>
  /// 主機名稱或IP地址
  /// </summary>
  /// <remarks>主機名稱或IP地址</remarks>
  public string HostName
  {
   get{return mstrHost;}
   set{mstrHost = value;}
  }

  /// <summary>
  /// 主機的端口號
  /// </summary>
  /// <remarks>主機的端口號</remarks>
  public int Port
  {
   get{return mintPort;}
   set{mintPort = value;}
  }

  #endregion

  #region 私有方法

  /// <summary>
  /// 向網絡訪問的基礎數據流中寫數據(發送命令碼)
  /// </summary>
  /// <param name="netStream">可以用於網絡訪問的基礎數據流</param>
  /// <param name="command">命令行</param>
  /// <remarks>向網絡訪問的基礎數據流中寫數據(發送命令碼)</remarks>
  private void WriteToNetStream(ref NetworkStream netStream,String command)
  {
   string strToSend = command + "/r/n";
   byte[] arrayToSend = System.Text.Encoding.ASCII.GetBytes(strToSend.ToCharArray());
      netStream.Write(arrayToSend,0,arrayToSend.Length);
  }

  /// <summary>
  /// 檢查命令行結果是否正確
  /// </summary>
  /// <param name="message">命令行的執行結果</param>
  /// <param name="check">正確標志</param>
  /// <returns>
  /// 類型:布爾
  /// 內容:true表示沒有錯誤,false為有錯誤
  /// </returns>
  /// <remarks>檢查命令行結果是否有錯誤</remarks>
  private bool CheckCorrect(string message,string check)
  {
   if(message.IndexOf(check) == -1)
    return false;
   else
    return true;
  }

  /// <summary>
  /// 郵箱中的未讀郵件數
  /// </summary>
  /// <param name="message">執行完LIST命令后的結果</param>
  /// <returns>
  /// 類型:整型
  /// 內容:郵箱中的未讀郵件數
  /// </returns>
  /// <remarks>郵箱中的未讀郵件數</remarks>
  private int GetMailNumber(string message)
  {
   string[] strMessage = message.Split(' ');
   return Int32.Parse(strMessage[1]);
  }

  /// <summary>
  /// 得到經過解碼后的郵件的內容
  /// </summary>
  /// <param name="encodingContent">解碼前的郵件的內容</param>
  /// <returns>
  /// 類型:字符串
  /// 內容:解碼后的郵件的內容
  /// </returns>
  /// <remarks>得到解碼后的郵件的內容</remarks>
  private string GetDecodeMailContent(string encodingContent)
  {
   string strContent = encodingContent.Trim();
   string strEncode = null;

   int iStart = strContent.IndexOf("Base64");
   if(iStart == -1)
    throw new Pop3Exception("郵件內容不是Base64編碼,請檢查");
   else
   {
    strEncode = strContent.Substring(iStart + 6,strContent.Length - iStart - 6);
    try
    {
     return SX.Encode.TransformToString(strEncode);
    }
    catch(SX.EncodeException exc)
    {
     throw new Pop3Exception(exc.Message);
    }
   }
  }

  #endregion

  /// <summary>
  /// 與主機建立連接
  /// </summary>
  /// <returns>
  /// 類型:布爾
  /// 內容:連接結果(true為連接成功,false為連接失敗)
  /// </returns>
  /// <remarks>與主機建立連接</remarks>
  public bool Connect()
  {
   if(mstrHost == null)
    throw new Exception("請提供SMTP主機名稱或IP地址!");
   if(mintPort == 0)
    throw new Exception("請提供SMTP主機的端口號");
   try
   {
    mtcpClient = new TcpClient(mstrHost,mintPort);
    mnetStream = mtcpClient.GetStream();
    m_stmReader = new StreamReader(mtcpClient.GetStream());

    string strMessage = m_stmReader.ReadLine();
    if(CheckCorrect(strMessage,"+OK") == true)
     return true;
    else
     return false;
   }
   catch(SocketException exc)
   {
    throw new Pop3Exception(exc.ToString());
   }
   catch(NullReferenceException exc)
   {
    throw new Pop3Exception(exc.ToString());
   }
  }

  #region Pop3命令

  /// <summary>
  /// 執行Pop3命令,並檢查執行的結果
  /// </summary>
  /// <param name="command">Pop3命令行</param>
  /// <returns>
  /// 類型:字符串
  /// 內容:Pop3命令的執行結果
  /// </returns>
  private string ExecuteCommand(string command)
  {
   string strMessage = null;  //執行Pop3命令后返回的消息

   try
   {
    //發送命令
    WriteToNetStream(ref mnetStream,command);

    //讀取多行
    if(command.Substring(0,4).Equals("LIST") || command.Substring(0,4).Equals("RETR") || command.Substring(0,4).Equals("UIDL")) //記錄STAT后的消息(其中包含郵件數)
    {
     strMessage = ReadMultiLine();

     if(command.Equals("LIST")) //記錄LIST后的消息(其中包含郵件數)
      mstrStatMessage = strMessage;
    }
     //讀取單行
    else
     strMessage = m_stmReader.ReadLine();

    //判斷執行結果是否正確
    if(CheckCorrect(strMessage,"+OK"))
     return strMessage;
    else
     return "Error";
   }
   catch(IOException exc)
   {
    throw new Pop3Exception(exc.ToString());
   }
  }

  /// <summary>
  /// 在Pop3命令中,LIST、RETR和UIDL命令的結果要返回多行,以點號(.)結尾,
  /// 所以如果想得到正確的結果,必須讀取多行
  /// </summary>
  /// <returns>
  /// 類型:字符串
  /// 內容:執行Pop3命令后的結果
  /// </returns>
  private string ReadMultiLine()
  {
   string strMessage = m_stmReader.ReadLine();
   string strTemp = null;
   while(strMessage != ".")
   {
    strTemp = strTemp + strMessage;
    strMessage = m_stmReader.ReadLine();
   }
   return strTemp;
  }

  //USER命令
  private string USER(string user)
  {
   return ExecuteCommand("USER " + user) + "/r/n";
  }

  //PASS命令
  private string PASS(string password)
  {
   return ExecuteCommand("PASS " + password) + "/r/n";
  }

  //LIST命令
  private string LIST()
  {
   return ExecuteCommand("LIST") + "/r/n";
  }

  //UIDL命令
  private string UIDL()
  {
   return ExecuteCommand("UIDL") + "/r/n";
  }

  //NOOP命令
  private string NOOP()
  {
   return ExecuteCommand("NOOP") + "/r/n";
  }

  //STAT命令
  private string STAT()
  {
   return ExecuteCommand("STAT") + "/r/n";
  }

  //RETR命令
  private string RETR(int number)
  {
   return ExecuteCommand("RETR " + number.ToString()) + "/r/n";
  }

  //DELE命令
  private string DELE(int number)
  {
   return ExecuteCommand("DELE " + number.ToString()) + "/r/n";
  }

  //QUIT命令
  private void Quit()
  {
   WriteToNetStream(ref mnetStream,"QUIT");
  }

  /// <summary>
  /// 收取郵件
  /// </summary>
  /// <param name="user">用戶名</param>
  /// <param name="password">口令</param>
  /// <returns>
  /// 類型:字符串數組
  /// 內容:解碼前的郵件內容
  /// </returns>
  private string[] ReceiveMail(string user,string password)
  {
   int iMailNumber = 0;  //郵件數

   if(USER(user).Equals("Error"))
    throw new Pop3Exception("用戶名不正確!");
   if(PASS(password).Equals("Error"))
    throw new Pop3Exception("用戶口令不正確!");
   if(STAT().Equals("Error"))
    throw new Pop3Exception("准備接收郵件時發生錯誤!");
   if(LIST().Equals("Error"))
    throw new Pop3Exception("得到郵件列表時發生錯誤!");

   try
   {
    iMailNumber = GetMailNumber(mstrStatMessage);

    //沒有新郵件
    if(iMailNumber == 0)
     return null;
    else
    {
     string[] strMailContent = new string[iMailNumber];

     for(int i = 1 ; i <= iMailNumber ; i++)
     {
      //讀取郵件內容
      strMailContent[i - 1] = GetDecodeMailContent(RETR(i));
     }
     return strMailContent;
    }
   }
   catch(Pop3Exception exc)
   {
    throw new Pop3Exception(exc.ToString());
   }
  }

  #endregion


  /// <summary>
  /// 收取郵件    
  /// </summary>
  /// <param name="user">用戶名</param>
  /// <param name="password">口令</param>
  /// <returns>
  /// 類型:字符串數組
  /// 內容:解碼前的郵件內容
  /// </returns>
  ///<remarks>收取郵箱中的未讀郵件</remarks>
  public string[] Receive(string user,string password)
  {
   try
   {
    return ReceiveMail(user,password);
   }
   catch(Pop3Exception exc)
   {
    throw new Pop3Exception(exc.ToString());
   }
  }

  /// <summary>
  /// 斷開所有與服務器的會話
  /// </summary>
  /// <remarks>斷開所有與服務器的會話</remarks>
  public void DisConnect()
  {
   try
   {
    Quit();
    if(m_stmReader != null)
     m_stmReader.Close();
    if(mnetStream != null)
     mnetStream.Close();
    if(mtcpClient != null)
     mtcpClient.Close();
   }
   catch(SocketException exc)
   {
    throw new Pop3Exception(exc.ToString());
   }
  }

  /// <summary>
  /// 刪除郵件
  /// </summary>
  /// <param name="number">郵件號</param>
  public void DeleteMail(int number)
  {
   //刪除郵件
   int iMailNumber = number + 1;
   if(DELE(iMailNumber).Equals("Error"))
    throw new Pop3Exception("刪除第" + iMailNumber.ToString() + "時出現錯誤!");
  }

 }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM