Pop3收取邮件

using System;
using System.Net.Sockets;
using System.Net;
using System.Security.Cryptography;
using System.IO;
// 类名:Pop3
// 功能:接收电子邮件
namespace 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() + "时出现错误!");
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ligengdipan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值