《Effective C#》学习笔记(七)---c#接收电子邮件类

using System;

using System.Net.Sockets;

using System.Net;

using System.Security.Cryptography;

using System.IO;

 

类名:Pop3        

功能:接收电子邮件         

/

 

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命令中,LISTRETRUIDL命令的结果要返回多行,以点号(.)结尾,

  /// 所以如果想得到正确的结果,必须读取多行

  /// </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() + "时出现错误!");

  }

 

 }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值