- 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命令中,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() + "时出现错误!");
- }
- }
- }
c#接收邮件类
最新推荐文章于 2020-03-30 07:30:14 发布