用ESMTP和POP3协议实现的邮件发送和接收
using System;using System.Collections.Generic;
using System.Text;
using
using
using System.Threading;
namespace YZOutLook
{
/// <summary>
/// 邮件实体类
/// </summary>
public class Mail
{
int _MailID;
string _MailFrom;
string[] _MailTo;
string _Subject;
string _Content;
DateTime _SendDate;
int _MailState;
/// <summary>
/// 邮件的自动编号
/// </summary>
public int MailID
{
get { return _MailID; }
set { _MailID = value; }
}
/// <summary>
/// 发件人邮箱
/// </summary>
public string MailFrom
{
get { return _MailFrom; }
set { _MailFrom = value; }
}
/// <summary>
/// 收件人邮箱
/// </summary>
public string[] MailTo
{
get { return _MailTo; }
set { _MailTo = value; }
}
/// <summary>
/// 主题
/// </summary>
public string Subject
{
get { return _Subject; }
set { _Subject = value; }
}
/// <summary>
/// 内容
/// </summary>
public string Content
{
get { return _Content; }
set { _Content = value; }
}
/// <summary>
/// 发送时间
/// </summary>
public DateTime SendDate
{
get { return _SendDate; }
set { _SendDate = value; }
}
/// <summary>
/// 邮件在哪个邮件箱里面 (发件箱:1 收件箱:2 草稿箱:3 垃圾箱:4
/// </summary>
public int MailState
{
get { return _MailState; }
set { _MailState = value; }
}
}
/// <summary>
/// 邮件的 发送和接收
/// </summary>
public class MailManager
{
NetworkStream ns=null;
string mailString = string.Empty;
public MailManager() { }
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="smtpServer">smtp服务器名或者IP</param>
/// <param name="port">smtp服务器开放的端口</param>
/// <param name="isEsmtp">是否需要验证</param>
/// <param name="userName">用户名</param>
/// <param name="userPwd">密码</param>
/// <param name="mail">邮件对象</param>
/// <returns></returns>
public bool SendMail(string smtpServer,int port,bool isEsmtp,string userName,string userPwd,Mail mail)
{
TcpClient client = new TcpClient();
IPAddress ip = Dns.GetHostAddresses(smtpServer)[0];
IPEndPoint remoteEP = new IPEndPoint(ip,port);
client.Connect(remoteEP);
if (client.Connected)
{
ns = client.GetStream();
if (GetStatusCode() != 220)
{
return false;
}
SendCmd("HELO " + smtpServer + "\r\n");
if (GetStatusCode() != 250)
{
return false;
}
if (isEsmtp)
{
SendCmd("AUTH LOGIN\r\n");
if (GetStatusCode() != 334)
{ return false; }
SendCmd(GetBase64String(userName) + "\r\n");
if (GetStatusCode() != 334)
{ return false; }
SendCmd(GetBase64String(userPwd) + "\r\n");
if (GetStatusCode() != 235)
{ return false; }
}
SendCmd("MAIL FROM:" + mail.MailFrom + "\r\n");
if (GetStatusCode() != 250)
{ return false; }
foreach (string to in mail.MailTo)
{
SendCmd("RCPT TO:" + to + "\r\n");
if (GetStatusCode() != 250)
{ return false; }
}
SendCmd("DATA \r\n");
if (GetStatusCode() != 354)
{ return false; }
StringBuilder content = new StringBuilder();
content.AppendFormat("From:{0}\r\n", mail.MailFrom);
string toTxt = string.Empty;
foreach (string to in mail.MailTo)
{
toTxt += to + ";";
}
toTxt = toTxt.Substring(0, toTxt.Length - 1);
content.AppendFormat("To:{0}\r\n", toTxt);
content.AppendFormat("Date:{0}\r\n", mail.SendDate.ToString());
content.AppendFormat("Subject:{0}\r\n", mail.Subject);
content.Append("\r\n");
content.Append(mail.Content);
content.Append("\r\n.\r\n");
SendCmd(content.ToString());
if (GetStatusCode() != 250)
{ return false; }
else
{
return true;
}
}
else
{
return false;
}
}
void SendCmd(string cmd)
{
byte[] data = Encoding.UTF8.GetBytes(cmd);
ns.Write(data, 0, data.Length);
ns.Flush();
}
int GetStatusCode()
{
byte[] data=new byte[1024];
int i = ns.Read(data, 0, data.Length);
string str = Encoding.UTF8.GetString(data,0,i);
if (str.Length > 3)
{str=str.Substring(0, 3); }
int code = 0;
try
{
code = int.Parse(str);
}
catch { }
return code;
}
string GetReceiveCode()
{
byte[] data = new byte[1024];
int i = ns.Read(data, 0, data.Length);
string str = Encoding.Default.GetString(data, 0, i);
return str;
}
string GetBase64String(string source)
{
byte[] data = Encoding.UTF8.GetBytes(source);
return Convert.ToBase64String(data);
}
/// <summary>
/// 接收邮件
/// </summary>
/// <param name="pop3Server">收件服务器的名或者IP</param>
/// <param name="port">收件服务器开放的端口</param>
/// <param name="userName">用户名</param>
/// <param name="userPwd">密码</param>
/// <param name="isSaveAtServer">接收完邮件后,是否在服务器存储</param>
/// <returns>返回邮件的数组</returns>
public Mail[] ReceiveMail(string pop3Server,int port,string userName,string userPwd,bool isSaveAtServer)
{
Mail[] mails = null;//邮件的数组
TcpClient client = new TcpClient();
IPAddress ip = Dns.GetHostAddresses(pop3Server)[0];
IPEndPoint remoteEP = new IPEndPoint(ip,port);
client.Connect(remoteEP);
if (client.Connected)
{
ns = client.GetStream();
if (GetReceiveCode().Substring(0, 3) != "+OK")
{ return null; }
SendCmd("USER " + userName + "\r\n");
if (GetReceiveCode().Substring(0, 3) != "+OK")
{ return null; }
SendCmd("PASS " + userPwd + "\r\n");
if (GetReceiveCode().Substring(0, 3) != "+OK")
{ return null; }
SendCmd("STAT \r\n");
string stat = GetReceiveCode();
if (stat.Substring(0, 3) != "+OK")
{ return null; }
string[] statTemp = stat.Split(' ');
int count = int.Parse(statTemp[1]);//邮件的封数
mails = new Mail[count];
for (int i = 1; i <= count; i++)
{
Mail model = new Mail();
SendCmd("RETR " + i.ToString() + "\r\n");
do
{
mailString += GetReceiveCode();
} while (mailString.IndexOf("\r\n.\r\n") == -1);
//获取邮件的信息
#region
int start = mailString.IndexOf("From:") + 5;
int end = mailString.IndexOf("\r\n", start);//From:aa\r\n
model.MailFrom = mailString.Substring(start, end - start);//发件人
start = mailString.IndexOf("To:") + 3;
end = mailString.IndexOf("\r\n", start);
model.MailTo = mailString.Substring(start, end - start).Split(';');
//获取发件的时间
start = mailString.IndexOf("Date:") + 5;
end = mailString.IndexOf("\r\n", start);
model.SendDate = DateTime.Parse(mailString.Substring(start, end - start));
//获取标题
start = mailString.IndexOf("Subject:") + 8;
end = mailString.IndexOf("\r\n", start);
model.Subject = mailString.Substring(start, end - start);
//获取内容
start = mailString.IndexOf("\r\n\r\n") + 1;
end = mailString.IndexOf(".", start);
model.Content = mailString.Substring(start, end - start);
#endregion
mailString = "";
mails[i-1] = model;
}
if (!isSaveAtServer)//不在服务器中保留邮件
{
for (int i = 1; i <= count; i++)
{
SendCmd("DELE "+i.ToString()+"\r\n");
}
}
SendCmd("QUIT\r\n");//退出
return mails;
}
else
{ return null; }
}
/// <summary>
/// 这是一个测试方法
/// </summary>
/// <param name="callback"></param>
public void Test(ReceiveMailCallBack callback)
{
Random ra = new Random();
ReceiveMailStateEventArgs args = new ReceiveMailStateEventArgs();
args.TotalMail = 10;
for (int i = 1; i <= 10; i++)
{
args.CurrMail=i;
args.CurrMailState = MailState.接收中;
callback(args, null);
if (args.Cancel)
{
break;
}
Thread.Sleep(2000);
args.CurrMailState = MailState.成功;
callback(args, null);
Thread.Sleep(1000);
}
}
/// <summary>
/// 接收邮件高级类,并且可以显示当前状态
/// </summary>
/// <param name="pop3Server">收件服务器的名或者IP</param>
/// <param name="port">收件服务器开放的端口</param>
/// <param name="userName">用户名</param>
/// <param name="userPwd">密码</param>
/// <param name="isSaveAtServer">接收完邮件后,是否在服务器存储</param>
/// <returns>返回邮件的数组</returns>
public Mail[] ReceiveMail(string pop3Server, int port, string userName, string userPwd, bool isSaveAtServer,ReceiveMailCallBack callback)
{
Mail[] mails = null;//邮件的数组
TcpClient client = new TcpClient();
IPAddress ip = Dns.GetHostAddresses(pop3Server)[0];
IPEndPoint remoteEP = new IPEndPoint(ip, port);
client.Connect(remoteEP);
if (client.Connected)
{
ns = client.GetStream();
if (GetReceiveCode().Substring(0, 3) != "+OK")
{ return null; }
SendCmd("USER " + userName + "\r\n");
if (GetReceiveCode().Substring(0, 3) != "+OK")
{ return null; }
SendCmd("PASS " + userPwd + "\r\n");
if (GetReceiveCode().Substring(0, 3) != "+OK")
{ return null; }
SendCmd("STAT \r\n");
string stat = GetReceiveCode();
if (stat.Substring(0, 3) != "+OK")
{ return null; }
string[] statTemp = stat.Split(' ');
int count = int.Parse(statTemp[1]);//邮件的封数
mails = new Mail[count];
ReceiveMailStateEventArgs args = new ReceiveMailStateEventArgs();
args.TotalMail = count;//总邮件数
for (int i = 1; i <= count; i++)
{
Mail model = new Mail();
args.CurrMail = i;//当前第几封邮件
args.CurrMailState = MailState.接收中;
callback(args, null);//回调用方法--------------------------------
if (args.Cancel)//取消邮件的接收
{ return null; }
SendCmd("RETR " + i.ToString() + "\r\n");
try
{
do
{
mailString += GetReceiveCode();
} while (mailString.IndexOf("\r\n.\r\n") == -1);
args.CurrMailState = MailState.成功;
callback(args, null);//回调用方法
}
catch
{
args.CurrMailState = MailState.失败;
callback(args, null);//回调用方法
continue;
}
//获取邮件的信息
#region
int start = mailString.IndexOf("From:") + 5;
int end = mailString.IndexOf("\r\n", start);//From:aa\r\n
model.MailFrom = mailString.Substring(start, end - start);//发件人
start = mailString.IndexOf("To:") + 3;
end = mailString.IndexOf("\r\n", start);
model.MailTo = mailString.Substring(start, end - start).Split(';');
//获取发件的时间
start = mailString.IndexOf("Date:") + 5;
end = mailString.IndexOf("\r\n", start);
model.SendDate = DateTime.Parse(mailString.Substring(start, end - start));
//获取标题
start = mailString.IndexOf("Subject:") + 8;
end = mailString.IndexOf("\r\n", start);
model.Subject = mailString.Substring(start, end - start);
//获取内容
start = mailString.IndexOf("\r\n\r\n") + 1;
end = mailString.IndexOf(".", start);
model.Content = mailString.Substring(start, end - start);
#endregion
mailString = "";
mails[i - 1] = model;
}
if (!isSaveAtServer)//不在服务器中保留邮件
{
for (int i = 1; i <= count; i++)
{
SendCmd("DELE " + i.ToString() + "\r\n");
}
}
SendCmd("QUIT\r\n");//退出
return mails;
}
else
{ return null; }
}
}
/// <summary>
/// 接收邮件状态 事件类
/// </summary>
public class ReceiveMailStateEventArgs
{
int _TotalMail;
int _CurrMail;
MailState _CurrMailState = MailState.接收中;
bool _Cancel = false;
/// <summary>
/// 总邮件数
/// </summary>
public int TotalMail
{
get { return _TotalMail; }
set { _TotalMail = value; }
}
/// <summary>
/// 当前第几封邮件
/// </summary>
public int CurrMail
{
get { return _CurrMail; }
set { _CurrMail = value; }
}
/// <summary>
/// 当前邮件的状态
/// </summary>
public MailState CurrMailState
{
get { return _CurrMailState; }
set { _CurrMailState = value; }
}
/// <summary>
/// 是否取消接收
/// </summary>
public bool Cancel
{
get { return _Cancel; }
set { _Cancel = value; }
}
}
/// <summary>
/// 当前邮件的状态
/// </summary>
public enum MailState
{
接收中,
成功,
失败
}
/// <summary>
/// 接收邮件时,用于通知外部信息 回调方法的委托
/// </summary>
/// <param name="args">状态数据</param>
/// <param name="obj">用于扩展使用的</param>
public delegate void ReceiveMailCallBack(ReceiveMailStateEventArgs args,object obj);
}