using System;
using System.Collections;
using System.IO;
using System.Text;
using System.Data;
using System.Net.Sockets;
namespace Baolee.GeneralMethod
{
/// <summary>
/// MailSender 的摘要说明。
/// </summary>
public class MailSender
{
#region // Fields
private ArrayList attachments;
private string body;
private string encoding;
private string from;
private string fromName;
private string htmlBody;
private bool isHtml;
private string languageEncoding;
private string password;
private int port;
private int priority;
private string server;
private string subject;
private string to;
private string toName;
private string userName;
#endregion
#region 建构函式
/// <summary>
///
/// </summary>
public MailSender()
{
this.server = "";
this.port = 0x19;
this.userName = "";
this.password = "";
this.from = "";
this.to = "";
this.fromName = "";
this.toName = "";
this.subject = "";
this.body = "";
this.htmlBody = "";
this.isHtml = false;
this.languageEncoding = "GB2312";
this.encoding = "8bit";
this.priority = 3;
this.attachments = new ArrayList();
}
#endregion
#region // Properties
/// <summary>
/// 附件 [AttachmentInfo]
/// </summary>
public IList Attachments
{
get
{
return this.attachments;
}
}
/// <summary>
/// 邮件正文
/// </summary>
public string Body
{
get
{
return this.body;
}
set
{
if (value != this.body)
{
this.body = value;
}
}
}
/// <summary>
/// 发件人地址
/// </summary>
public string From
{
get
{
return this.from;
}
set
{
if (value != this.from)
{
this.from = value;
}
}
}
/// <summary>
/// 发件人姓名
/// </summary>
public string FromName
{
get
{
return this.fromName;
}
set
{
if (value != this.fromName)
{
this.fromName = value;
}
}
}
/// <summary>
/// 超文本格式的邮件正文
/// </summary>
public string HtmlBody
{
get
{
return this.htmlBody;
}
set
{
if (value != this.htmlBody)
{
this.htmlBody = value;
}
}
}
/// <summary>
/// 是否是html格式的邮件
/// </summary>
public bool IsHtml
{
get
{
return this.isHtml;
}
set
{
if (value != this.isHtml)
{
this.isHtml = value;
}
}
}
/// <summary>
/// 语言编码 [默认为GB2312]
/// </summary>
public string LanguageEncoding
{
get
{
return this.languageEncoding;
}
set
{
if (value != this.languageEncoding)
{
this.languageEncoding = value;
}
}
}
/// <summary>
/// 邮件编码 [默认为8bit]
/// </summary>
public string MailEncoding
{
get
{
return this.encoding;
}
set
{
if (value != this.encoding)
{
this.encoding = value;
}
}
}
/// <summary>
/// 密码 [如果需要身份验证的话]
/// </summary>
public string Password
{
get
{
return this.password;
}
set
{
if (value != this.password)
{
this.password = value;
}
}
}
/// <summary>
/// SMTP服务器端口 [默认为25]
/// </summary>
public int Port
{
get
{
return this.port;
}
set
{
if (value != this.port)
{
this.port = value;
}
}
}
/// <summary>
/// 邮件优先级 [默认为3]
/// </summary>
public int Priority
{
get
{
return this.priority;
}
set
{
if (value != this.priority)
{
this.priority = value;
}
}
}
/// <summary>
/// SMTP服务器域名
/// </summary>
public string Server
{
get
{
return this.server;
}
set
{
if (value != this.server)
{
this.server = value;
}
}
}
/// <summary>
/// 邮件的主题
/// </summary>
public string Subject
{
get
{
return this.subject;
}
set
{
if (value != this.subject)
{
this.subject = value;
}
}
}
/// <summary>
/// 收件人地址
/// </summary>
public string To
{
get
{
return this.to;
}
set
{
if (value != this.to)
{
this.to = value;
}
}
}
/// <summary>
/// 收件人姓名
/// </summary>
public string ToName
{
get
{
return this.toName;
}
set
{
if (value != this.toName)
{
this.toName = value;
}
}
}
/// <summary>
/// 用户名 [如果需要身份验证的话]
/// </summary>
public string UserName
{
get
{
return this.userName;
}
set
{
if (value != this.userName)
{
this.userName = value;
}
}
}
#endregion
#region // Nested Types
/// <summary>
///
/// </summary>
public struct AttachmentInfo
{
private string fileName;
private string bytes;
public string FileName
{
get
{
return this.fileName;
}
set
{
this.fileName = Path.GetFileName(value);
}
}
/// <summary>
///
/// </summary>
public string Bytes
{
get
{
return this.bytes;
}
set
{
if (value != this.bytes)
{
this.bytes = value;
}
}
}
/// <summary>
///
/// </summary>
/// <param name="ifileName"></param>
/// <param name="stream"></param>
public AttachmentInfo(string ifileName, Stream stream)
{
this.fileName = Path.GetFileName(ifileName);
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int) stream.Length);
this.bytes = Convert.ToBase64String(buffer);
}
/// <summary>
///
/// </summary>
/// <param name="ifileName"></param>
/// <param name="ibytes"></param>
public AttachmentInfo(string ifileName, byte[] ibytes)
{
this.fileName = Path.GetFileName(ifileName);
this.bytes = Convert.ToBase64String(ibytes);
}
/// <summary>
///
/// </summary>
/// <param name="path"></param>
public AttachmentInfo(string path)
{
this.fileName = Path.GetFileName(path);
FileStream stream = new FileStream(path, FileMode.Open);
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int) stream.Length);
this.bytes = Convert.ToBase64String(buffer);
stream.Close();
}
}
#endregion
#region // Methods
/// <summary>
/// 发出命令并判断返回信息是否正确
/// </summary>
/// <param name="netStream">来自TcpClient的流</param>
/// <param name="command">命令</param>
/// <param name="state">正确的状态码</param>
/// <returns>是否正确</returns>
protected bool Command(NetworkStream netStream, string command, string state)
{
bool flag = false;
try
{
this.WriteString(netStream, command);
if (this.ReadString(netStream).IndexOf(state) != -1)
{
flag = true;
}
}
catch (Exception)
{
}
return flag;
}
/// <summary>
/// 从流中读取字符
/// </summary>
/// <param name="netStream">来自TcpClient的流</param>
/// <returns>读取的字符</returns>
protected string ReadString(NetworkStream netStream)
{
string text = null;
byte[] buffer = new byte[0x400];
if (netStream.Read(buffer, 0, buffer.Length) > 0)
{
text = Encoding.Default.GetString(buffer);
}
return text;
}
/// <summary>
/// 发送邮件
/// </summary>
public void SendMail()
{
TcpClient client = null;
try
{
client = new TcpClient(this.server, this.port);
}
catch (Exception)
{
throw new Exception("无法连接服务器");
}
this.ReadString(client.GetStream());
if (!this.Command(client.GetStream(), "EHLO Localhost", "250"))
{
throw new Exception("登陆阶段失败");
}
if (this.userName != "")
{
if (!this.Command(client.GetStream(), "AUTH LOGIN", "334"))
{
throw new Exception("身份验证阶段失败");
}
string command = this.ToBase64(this.userName);
if (!this.Command(client.GetStream(), command, "334"))
{
throw new Exception("身份验证阶段失败");
}
string text2 = this.ToBase64(this.password);
if (!this.Command(client.GetStream(), text2, "235"))
{
throw new Exception("身份验证阶段失败");
}
}
this.WriteString(client.GetStream(), "mail From: " + this.from);
this.WriteString(client.GetStream(), "rcpt to: " + this.to);
this.WriteString(client.GetStream(), "data");
this.WriteString(client.GetStream(), "Date: " + DateTime.Now);
this.WriteString(client.GetStream(), "From: " + this.fromName + "<" + this.from + ">");
this.WriteString(client.GetStream(), "Subject: " + this.subject);
this.WriteString(client.GetStream(), "To:" + this.toName + "<" + this.to + ">");
this.WriteString(client.GetStream(), "Content-Type: multipart/mixed; boundary=/"unique-boundary-1/"");
this.WriteString(client.GetStream(), "Reply-To:" + this.from);
this.WriteString(client.GetStream(), "X-Priority:" + this.priority);
this.WriteString(client.GetStream(), "MIME-Version:1.0");
this.WriteString(client.GetStream(), "Content-Transfer-Encoding:" + this.encoding);
this.WriteString(client.GetStream(), "X-Mailer:GerenalMethod.MailSender");
this.WriteString(client.GetStream(), "");
this.WriteString(client.GetStream(), this.ToBase64("This is a multi-part message in MIME format."));
this.WriteString(client.GetStream(), "");
this.WriteString(client.GetStream(), "--unique-boundary-1");
this.WriteString(client.GetStream(), "Content-Type: multipart/alternative;Boundary=/"unique-boundary-2/"");
this.WriteString(client.GetStream(), "");
if (!this.isHtml)
{
this.WriteString(client.GetStream(), "--unique-boundary-2");
this.WriteString(client.GetStream(), "Content-Type: text/plain;charset=" + this.languageEncoding);
this.WriteString(client.GetStream(), "Content-Transfer-Encoding:" + this.encoding);
this.WriteString(client.GetStream(), "");
this.WriteString(client.GetStream(), this.body);
this.WriteString(client.GetStream(), "");
this.WriteString(client.GetStream(), "--unique-boundary-2--");
this.WriteString(client.GetStream(), "");
}
else
{
this.WriteString(client.GetStream(), "--unique-boundary-2");
this.WriteString(client.GetStream(), "Content-Type: text/html;charset=" + this.languageEncoding);
this.WriteString(client.GetStream(), "Content-Transfer-Encoding:" + this.encoding);
this.WriteString(client.GetStream(), "");
this.WriteString(client.GetStream(), this.htmlBody);
this.WriteString(client.GetStream(), "");
this.WriteString(client.GetStream(), "--unique-boundary-2--");
this.WriteString(client.GetStream(), "");
}
for (int i = 0; i < this.attachments.Count; i++)
{
this.WriteString(client.GetStream(), "--unique-boundary-1");
AttachmentInfo info = (AttachmentInfo) this.attachments[i];
this.WriteString(client.GetStream(), "Content-Type: application/octet-stream;name=/"" + info.FileName + "/"");
this.WriteString(client.GetStream(), "Content-Transfer-Encoding: base64");
info = (AttachmentInfo) this.attachments[i];
this.WriteString(client.GetStream(), "Content-Disposition:attachment;filename=/"" + info.FileName + "/"");
this.WriteString(client.GetStream(), "");
info = (AttachmentInfo) this.attachments[i];
this.WriteString(client.GetStream(), info.Bytes);
this.WriteString(client.GetStream(), "");
}
this.Command(client.GetStream(), ".", "250");
client.Close();
}
/// <summary>
/// 字符串编码为Base64
/// </summary>
/// <param name="str">字符串</param>
/// <returns>Base64编码的字符串</returns>
protected string ToBase64(string str)
{
try
{
str = Convert.ToBase64String(Encoding.Default.GetBytes(str.ToCharArray()));
}
catch (Exception)
{
}
return str;
}
/// <summary>
/// 向流中写入字符
/// </summary>
/// <param name="netStream">来自TcpClient的流</param>
/// <param name="str">写入的字符</param>
protected void WriteString(NetworkStream netStream, string str)
{
str = str + "/r/n";
byte[] bytes = Encoding.GetEncoding(this.languageEncoding).GetBytes(str.ToCharArray());
int offset = 0;
int length = bytes.Length;
int num3 = 0;
int num4 = 0x4b;
int count = num4;
try
{
if (length > 0x4b)
{
if (((length / num4) * num4) < length)
{
num3 = (length / num4) + 1;
}
else
{
num3 = length / num4;
}
for (int i = 0; i < num3; i++)
{
offset = i * num4;
if (i == (num3 - 1))
{
count = length - (i * num4);
}
netStream.Write(bytes, offset, count);
}
}
else
{
netStream.Write(bytes, 0, bytes.Length);
}
}
catch (Exception)
{
}
}
#endregion
}
}