⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pop3mailclient.cs

📁 《征服Ajax》原书的例题源码
💻 CS
📖 第 1 页 / 共 2 页
字号:
// POP3 Client
// ===========
//
// copyright by Peter Huber, Singapore, 2006
// this code is provided as is, bugs are probable, free for any use at own risk, no 
// responsibility accepted. All rights, title and interest in and to the accompanying content retained.  :-)
//
// based on POP3 Client as a C# Class, by Bill Dean, http://www.codeproject.com/csharp/Pop3MailClient.asp 
// based on Retrieve Mail From a POP3 Server Using C#, by Agus Kurniawan, http://www.codeproject.com/csharp/popapp.asp 
// based on Post Office Protocol - Version 3, http://www.ietf.org/rfc/rfc1939.txt

using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Net.Security;
using System.Text;


namespace Mail {
  // Supporting classes and structs
  // ==============================

  /// <summary>
  /// Combines Email ID with Email UID for one email
  /// The POP3 server assigns to each message a unique Email UID, which will not change for the life time
  /// of the message and no other message should use the same.
  /// 
  /// Exceptions:
  /// Throws Pop3Exception if there is a serious communication problem with the POP3 server, otherwise
  /// 
  /// </summary>
  public struct EmailUid {
    /// <summary>
    /// used in POP3 commands to indicate which message (only valid in the present session)
    /// </summary>
    public int EmailId;
    /// <summary>
    /// Uid is always the same for a message, regardless of session
    /// </summary>
    public string Uid;

    /// <summary>
    /// constructor
    /// </summary>
    public EmailUid(int EmailId, string Uid) {
      this.EmailId = EmailId;
      this.Uid = Uid;
    }
  }


  /// <summary>
  /// If anything goes wrong within Pop3MailClient, a Pop3Exception is raised
  /// </summary>
  public class Pop3Exception:ApplicationException {
    /// <summary>
    /// Pop3 exception with no further explanation
    /// </summary>
    public Pop3Exception() { }
    /// <summary>
    /// Pop3 exception with further explanation
    /// </summary>
    public Pop3Exception(string ErrorMessage) : base(ErrorMessage) { }
  }


  /// <summary>
  /// A pop 3 connection goes through the following states:
  /// </summary>
  public enum Pop3ConnectionStateEnum {
    /// <summary>
    /// undefined
    /// </summary>
    None=0,
    /// <summary>
    /// not connected yet to POP3 server
    /// </summary>
    Disconnected,
    /// <summary>
    /// TCP connection has been opened and the POP3 server has sent the greeting. POP3 server expects user name and password
    /// </summary>
    Authorization,
    /// <summary>
    /// client has identified itself successfully with the POP3, server has locked all messages 
    /// </summary>
    Connected,
    /// <summary>
    /// QUIT command was sent, the server has deleted messages marked for deletion and released the resources
    /// </summary>
    Closed
  }


  // Delegates for Pop3MailClient
  // ============================

  /// <summary>
  /// If POP3 Server doesn't react as expected or this code has a problem, but
  /// can continue with the execution, a Warning is called.
  /// </summary>
  /// <param name="WarningText"></param>
  /// <param name="Response">string received from POP3 server</param>
  public delegate void WarningHandler(string WarningText, string Response);


  /// <summary>
  /// Traces all the information exchanged between POP3 client and POP3 server plus some
  /// status messages from POP3 client.
  /// Helpful to investigate any problem.
  /// Console.WriteLine() can be used
  /// </summary>
  public delegate void TraceHandler(string TraceText);


  // Pop3MailClient Class
  // ====================  

  /// <summary>
  /// provides access to emails on a POP3 Server
  /// </summary>
  public class Pop3MailClient {

    //Events
    //------

    /// <summary>
    /// Called whenever POP3 server doesn't react as expected, but no runtime error is thrown.
    /// </summary>
    public event WarningHandler Warning;

    /// <summary>
    /// call warning event
    /// </summary>
    /// <param name="methodName">name of the method where warning is needed</param>
    /// <param name="response">answer from POP3 server causing the warning</param>
    /// <param name="warningText">explanation what went wrong</param>
    /// <param name="warningParameters"></param>
    protected void CallWarning(string methodName, string response, string warningText, params object[] warningParameters) {
      try {
        warningText = string.Format(warningText, warningParameters);
      } catch {
      }
      if (Warning!=null) {
        Warning(methodName + ": " + warningText, response);
      }
      CallTrace("!! {0}", warningText);
    }


    /// <summary>
    /// Shows the communication between PopClient and PopServer, including warnings
    /// </summary>
    public event TraceHandler Trace;

    /// <summary>
    /// call Trace event
    /// </summary>
    /// <param name="text">string to be traced</param>
    /// <param name="parameters"></param>
    protected void CallTrace(string text, params object[] parameters) {
      if (Trace!=null) {
        Trace(DateTime.Now.ToString("hh:mm:ss ") + popServer + " " + string.Format(text, parameters));
      }
    }

    /// <summary>
    /// Trace information received from POP3 server
    /// </summary>
    /// <param name="text">string to be traced</param>
    /// <param name="parameters"></param>
    protected void TraceFrom(string text, params object[] parameters) {
      if (Trace!=null) {
        CallTrace("   " + string.Format(text, parameters));
      }
    }


    //Properties
    //----------

    /// <summary>
    /// Get POP3 server name
    /// </summary>
    public string PopServer {
      get { return popServer; }
    }
    /// <summary>
    /// POP3 server name
    /// </summary>
    protected string popServer;


    /// <summary>
    /// Get POP3 server port
    /// </summary>
    public int Port {
      get { return port; }
    }
    /// <summary>
    /// POP3 server port
    /// </summary>
    protected int port;


    /// <summary>
    /// Should SSL be used for connection with POP3 server ?
    /// </summary>
    public bool UseSSL {
      get { return useSSL; }
    }
    /// <summary>
    /// Should SSL be used for connection with POP3 server ?
    /// </summary>
    private bool useSSL;


    /// <summary>
    /// should Pop3MailClient automatically reconnect if POP3 server has dropped the 
    /// connection due to a timeout ?
    /// </summary>
    public bool IsAutoReconnect {
      get { return isAutoReconnect; }
      set { isAutoReconnect = value; }
    }
    private bool isAutoReconnect = false;
    //timeout has occurred, we try to perform an autoreconnect
    private bool isTimeoutReconnect = false;



    /// <summary>
    /// Get / set read timeout (miliseconds)
    /// </summary>
    public int ReadTimeout {
      get { return readTimeout; }
      set {
        readTimeout = value;
        if (pop3Stream!=null && pop3Stream.CanTimeout) {
          pop3Stream.ReadTimeout = readTimeout;
        }
      }
    }
    /// <summary>
    /// POP3 server read timeout
    /// </summary>
    protected int readTimeout = -1;


    /// <summary>
    /// Get owner name of mailbox on POP3 server
    /// </summary>
    public string Username {
      get { return username; }
    }
    /// <summary>
    /// Owner name of mailbox on POP3 server
    /// </summary>
    protected string username;


    /// <summary>
    /// Get password for mailbox on POP3 server
    /// </summary>
    public string Password {
      get { return password; }
    }
    /// <summary>
    /// Password for mailbox on POP3 server
    /// </summary>
    protected string password;


    /// <summary>
    /// Get connection status with POP3 server
    /// </summary>
    public Pop3ConnectionStateEnum Pop3ConnectionState {
      get { return pop3ConnectionState; }
    }
    /// <summary>
    /// connection status with POP3 server
    /// </summary>
    protected Pop3ConnectionStateEnum pop3ConnectionState = Pop3ConnectionStateEnum.Disconnected;


    // Methods
    // -------

    /// <summary>
    /// set POP3 connection state
    /// </summary>
    protected void setPop3ConnectionState(Pop3ConnectionStateEnum State) {
      pop3ConnectionState = State;
      CallTrace("   Pop3MailClient Connection State {0} reached", State);
    }

    /// <summary>
    /// throw exception if POP3 connection is not in the required state
    /// </summary>
    protected void EnsureState(Pop3ConnectionStateEnum requiredState) {
      if (pop3ConnectionState!=requiredState) {
        // wrong connection state
        throw new Pop3Exception("GetMailboxStats only accepted during connection state: " + requiredState.ToString() + 
              "\n The connection to server "+ popServer + " is in state " + pop3ConnectionState.ToString());
      }
    }


    //private fields
    //--------------
    /// <summary>
    /// TCP to POP3 server
    /// </summary>
    private TcpClient serverTcpConnection;
    /// <summary>
    /// Stream from POP3 server with or without SSL
    /// </summary>
    private Stream pop3Stream;
    /// <summary>
    /// Reader for POP3 message
    /// </summary>
    protected StreamReader pop3StreamReader;
    /// <summary>
    /// char 'array' for carriage return / line feed
    /// </summary>
    protected string CRLF = "\r\n";


    //public methods
    //--------------

    /// <summary>
    /// Make POP3 client ready to connect to POP3 server
    /// </summary>
    /// <param name="PopServer"><example>pop.gmail.com</example></param>
    /// <param name="Port"><example>995</example></param>
    /// <param name="useSSL">True: SSL is used for connection to POP3 server</param>
    /// <param name="Username"><example>abc@gmail.com</example></param>
    /// <param name="Password">Secret</param>
    public Pop3MailClient(string PopServer, int Port, bool useSSL, string Username, string Password) {
      this.popServer = PopServer;
      this.port = Port;
      this.useSSL = useSSL;
      this.username = Username;
      this.password = Password;
    }


    /// <summary>
    /// Connect to POP3 server
    /// </summary>
    public void Connect() {
      if (pop3ConnectionState!=Pop3ConnectionStateEnum.Disconnected &&
        pop3ConnectionState!=Pop3ConnectionStateEnum.Closed && 
        !isTimeoutReconnect) {
        CallWarning("connect", "", "Connect command received, but connection state is: " + pop3ConnectionState.ToString());
      } else {
        //establish TCP connection
        try {
          CallTrace("   Connect at port {0}", port);
          serverTcpConnection = new TcpClient(popServer, port);
        } catch (Exception ex) {
          throw new Pop3Exception("Connection to server "+ popServer + ", port " + port + " failed.\nRuntime Error: "+ex.ToString());
        }

        if (useSSL) {
          //get SSL stream
          try {
            CallTrace("   Get SSL connection");
            pop3Stream = new SslStream(serverTcpConnection.GetStream(), false);
            pop3Stream.ReadTimeout = readTimeout;
          } catch (Exception ex) {
            throw new Pop3Exception("Server " + popServer + " found, but cannot get SSL data stream.\nRuntime Error: "+ex.ToString());
          }

          //perform SSL authentication
          try {
            CallTrace("   Get SSL authentication");
            ((SslStream)pop3Stream).AuthenticateAsClient(popServer);
          } catch (Exception ex) {
            throw new Pop3Exception("Server " + popServer + " found, but problem with SSL Authentication.\nRuntime Error: " + ex.ToString());
          }
        } else {
          //create a stream to POP3 server without using SSL
          try {
            CallTrace("   Get connection without SSL");
            pop3Stream = serverTcpConnection.GetStream();
            pop3Stream.ReadTimeout = readTimeout;
          } catch (Exception ex) {
            throw new Pop3Exception("Server " + popServer + " found, but cannot get data stream (without SSL).\nRuntime Error: "+ex.ToString());
          }
        }
        //get stream for reading from pop server
        //POP3 allows only US-ASCII. The message will be translated in the proper encoding in a later step
        try {
          pop3StreamReader= new StreamReader(pop3Stream, Encoding.ASCII);
        } catch (Exception ex) {
          if (useSSL) {
            throw new Pop3Exception("Server " + popServer + " found, but cannot read from SSL stream.\nRuntime Error: " + ex.ToString());
          } else {
            throw new Pop3Exception("Server " + popServer + " found, but cannot read from stream (without SSL).\nRuntime Error: " + ex.ToString());
          }
        }

        //ready for authorisation
        string response;
        if (!readSingleLine(out response)) {
          throw new Pop3Exception("Server " + popServer + " not ready to start AUTHORIZATION.\nMessage: " + response);
        }
        setPop3ConnectionState(Pop3ConnectionStateEnum.Authorization);

        //send user name
        if (!executeCommand("USER "+ username, out response)) {
          throw new Pop3Exception("Server " + popServer + " doesn't accept username '" + username + "'.\nMessage: " + response);
        }

        //send password
        if (!executeCommand("PASS " + password, out response)) {
          throw new Pop3Exception("Server " + popServer + " doesn't accept password '" + password + "' for user '" + username + "'.\nMessage: " + response);
        }

        setPop3ConnectionState(Pop3ConnectionStateEnum.Connected);
      }
    }


    /// <summary>
    /// Disconnect from POP3 Server
    /// </summary>
    public void Disconnect() {
      if (pop3ConnectionState==Pop3ConnectionStateEnum.Disconnected ||
        pop3ConnectionState==Pop3ConnectionStateEnum.Closed) {
        CallWarning("disconnect", "", "Disconnect received, but was already disconnected.");
      } else {
        //ask server to end session and possibly to remove emails marked for deletion
        try {
          string response;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -