zoukankan      html  css  js  c++  java
  • 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() + "时出现错误!");
      }

     }
    }
  • 相关阅读:
    jquery实现表格文本框淡入更改值后淡出
    硬件抽象层
    第八章读书笔记
    Linux驱动——LED闪烁
    编写Linux驱动与统计单词个数
    在开发板上安装Android
    源代码的下载和编译
    初学Git随笔
    Ubuntu Linux环境下的Android开发环境的配置
    Android系统移植于驱动开发概述
  • 原文地址:https://www.cnblogs.com/kevinGao/p/2305564.html
Copyright © 2011-2022 走看看