-
使用系統;
使用 System.Collections.Generic;
使用 System.Net.Sockets;
使用系統.IO;
使用系統文字;
使用系統集合;
公共類別MailSender
{
/// <摘要>
/// SMTP 伺服器域名
/// </摘要>
公共字串伺服器
{
取得{返回伺服器; }
設定 { if (value != server) server = value; }
} 私有字串伺服器 = "";
/// <摘要>
/// SMTP伺服器連接埠 [預設為25]
/// </摘要>
公共連接埠
{
獲取{返回連接埠; }
設定 { if (值!=連接埠) 連接埠 = 值; }
} 私有 int 連接埠 = 25;
/// <摘要>
/// 使用者名稱 [如果需要身份驗證的話]
/// </摘要>
公有字串使用者名
{
取得 { 返回使用者名稱; }
設定 { if (value != userName) userName = value; }
} 私有字串使用者名稱 = "";
/// <摘要>
/// 密碼 [如果需要驗證的話]
/// </摘要>
公共字串 密碼
{
獲取{返回密碼; }
set { if (值!=密碼) 密碼 = 值; }
} 私有字串密碼 = "";
/// <摘要>
/// 寄件者地址
/// </摘要>
公共字串來自
{
得到{返回; }
設定 { if (value != from) from = value; }
} 私有字串 from = "";
/// <摘要>
/// 食譜地址
/// </摘要>
公共字串 至
{
得到{返回; }
設定 { if (value != to) to = value; }
} 私有字串 = "";
/// <摘要>
/// 寄件者姓名
/// </摘要>
公共字串寄件者名稱
{
取得 { 返回 fromName; }
設定 { if (value != fromName) fromName = value; }
} 私有字串 fromName = "";
/// <摘要>
/// 姓名姓名
/// </摘要>
公有字串 ToName
{
取得 { 返回名稱; }
設定 { if (value != toName) toName = value; }
} 私有字串 toName = "";
/// <摘要>
/// 郵件的主題
/// </摘要>
公共字串主題
{
獲取{返回主題; }
設定 { if (值!= 主題) 主題 = 值; }
} 私有字串主題 = "";
/// <摘要>
/// 郵件正文
/// </摘要>
公共字串主體
{
取得{返回主體; }
設定 { if (value!= body) body = value; }
} 私有字串主體 = "";
/// <摘要>
/// 超文本格式的郵件正文
/// </摘要>
公共字串 HtmlBody
{
取得{返回htmlBody; }
設定 { if (value != htmlBody) htmlBody = value; }
} 私有字串 htmlBody = "";
/// <摘要>
/// 是否是html格式的郵件
/// </摘要>
public bool IsHtml
{
取得 { 返回 isHtml; }
設定 { if (value != isHtml) isHtml = value; }
} private bool isHtml = false;
/// <摘要>
/// 語言編碼 [預設為GB2312]
/// </摘要>
公共字串語言編碼
{
取得{返回語言編碼; }
設定 { if (value != languageEncoding) languageEncoding = value; }
} 私有字串 languageEncoding = "GB2312";
/// <摘要>
/// 郵件編碼 [預設為8bit]
/// </摘要>
公共字串郵件編碼
{
取得{返回編碼; }
設定 { if (值!= 編碼) 編碼 = 值; }
} 私有字串編碼 = "8bit";
/// <摘要>
/// 郵件優先權 [預設為3]
/// </摘要>
公共整數優先級
{
獲取{返回優先權; }
set { if (值!=優先權) 優先權 = 值; }
} 私有 int 優先權 = 3;
/// <摘要>
/// 附件 [AttachmentInfo]
/// </摘要>
公共 IList 附件
{
取得{返回附件; }
// 設定 { if (value != Attachments) Attachments = value; }
} 私有 ArrayList 附件 = new ArrayList();
/// <摘要>
/// 傳送郵件
/// </摘要>
公共無效SendMail()
{
//建立TcpClient對象,並建立連接
TcpClient tcp = null;
嘗試
{
tcp = new TcpClient(伺服器, 連接埠);
}
catch(異常前)
{
字串錯誤= ex.Message;
throw new Exception("無法連接伺服器");
}
ReadString(tcp.GetStream());//取得連線資訊
// 開始進行伺服器認證
// 如果狀態碼是250則表示操作成功
if (!Command(tcp.GetStream(), "EHLO Localhost", "250"))
throw new Exception("登陸階段失敗");
if (用戶名!= "")
{
// 需要身份驗證
if (!Command(tcp.GetStream(), "驗證登入", "334"))
throw new Exception("身份驗證階段失敗");
字串 nameB64 = ToBase64(使用者名稱); // 這裡將使用者名稱轉換為Base64碼
if (!Command(tcp.GetStream(), nameB64, "334"))
throw new Exception("身份驗證階段失敗");
字串 passB64 = ToBase64(密碼); // 這裡將密碼轉換為Base64碼
if (!Command(tcp.GetStream(), passB64, "235"))
throw new Exception("身份驗證階段失敗");
}
// 準備好要傳送
WriteString(tcp.GetStream(), "郵件寄件者:" + from);
WriteString(tcp.GetStream(), "rcpt 至:" + to);
WriteString(tcp.GetStream(), "資料");
// 傳送郵件頭
WriteString(tcp.GetStream(), "日期: " + DateTime.Now); // 時間
WriteString(tcp.GetStream(), "寄件者:" + fromName + "<" + from + ">"); // 寄件人
WriteString(tcp.GetStream(), "主題:" + 主題); // 主題
WriteString(tcp.GetStream(), "收件者:" + toName + "<" + to + ">"); // 需求
//郵件格式
WriteString(tcp.GetStream(), "內容類型:多部分/混合;邊界="unique-boundary-1"");
WriteString(tcp.GetStream(), "回覆:" + from); // 回覆地址
WriteString(tcp.GetStream(), "X-優先權:" + 優先權); // 優先權
WriteString(tcp.GetStream(), "MIME 版本:1.0"); // MIME 版本
// 資料ID,方便
// WriteString (tcp.GetStream(), "Message-Id: " + DateTime.Now.ToFileTime() + "@security.com ");
WriteString(tcp.GetStream(), "內容傳輸編碼:" + 編碼); // 內容編碼
WriteString(tcp.GetStream(), "X-Mailer:JcPersonal.Utility.MailSender"); // 郵件發送者
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), ToBase64("這是一則 MIME 格式的多部分訊息。"));
WriteString(tcp.GetStream(), "");
// 從此處開始進行分隔輸入
WriteString(tcp.GetStream(), "--unique-boundary-1");
// 在此定義第二個分隔符
WriteString(tcp.GetStream(), "Content-Type: multipart/alternative;Boundary="unique-boundary-2"");
WriteString(tcp.GetStream(), "");
if (!isHtml)
{
// 文字訊息
WriteString(tcp.GetStream(), "--unique-boundary-2");
WriteString(tcp.GetStream(), "Content-Type: text/plain;charset=" + languageEncoding);
WriteString(tcp.GetStream(), "內容傳輸編碼:" + 編碼);
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), body);
WriteString(tcp.GetStream(), "");//一部分寫完之後就寫如空訊息,分段
WriteString(tcp.GetStream(), "--unique-boundary-2--");//分隔符號的結束符號,尾巴後面多了--
WriteString(tcp.GetStream(), "");
}
別的
{
//html資訊
WriteString(tcp.GetStream(), "--unique-boundary-2");
WriteString(tcp.GetStream(), "Content-Type: text/html;charset=" + languageEncoding);
WriteString(tcp.GetStream(), "內容傳輸編碼:" + 編碼);
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), htmlBody);
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), "--unique-boundary-2--");//分隔符號的結束符號,尾巴後面多了--
WriteString(tcp.GetStream(), "");
}
// 傳送附件
// 對檔案清單做循環
for (int i = 0; i < 附件數; i++)
{
WriteString(tcp.GetStream(), "--unique-boundary-1"); // 郵件內容分隔符
WriteString(tcp.GetStream(), "內容型別: application/octet-stream;name="" + ((AttachmentInfo)attachments[i]).FileName + """); // 檔案格式
WriteString(tcp.GetStream(), "內容傳輸編碼:base64"); // 內容的編碼
WriteString(tcp.GetStream(), "Content-Disposition:attachment;filename="" + ((AttachmentInfo)attachments[i]).FileName + """); // 檔名
WriteString(tcp.GetStream(), "");
WriteString(tcp.GetStream(), ((AttachmentInfo)attachments[i]).Bytes); // 寫入檔案的內容
WriteString(tcp.GetStream(), "");
}
命令(tcp.GetStream(),“。”,“250”); //最後寫完了,輸入“.”
// 關閉連線
tcp.Close();
}
/// <摘要>
/// 在流中寫入字符
/// </摘要>
/// <param name="netStream">來自TcpClient的流</param>
/// <param name="str">寫入的字元</param>
protected void WriteString(NetworkStream netStream, 字串 str)
{
字串=字串+“”; // 加入換行符
// 將命令列轉換為byte[]
byte[] bWrite = Encoding.GetEncoding(languageEncoding).GetBytes(str.ToCharArray());
//由於每次寫入的資料長度是有限制的,所以我們將每次寫入的資料長度定在75個位元組,一旦指令長度超過了75,就分步寫入。
int 開始 = 0;
int 長度 = bWrite.Length;
int 頁 = 0;
整數大小= 75;
int 計數 = 大小;
嘗試
{
如果(長度 > 75)
{
// 資料分頁
if ((長度/尺寸) * 尺寸 < 長度)
頁=長度/大小+1;
別的
頁=長度/尺寸;
for (int i = 0; i < 頁; i++)
{
開始 = i * 大小;
if (i == 頁 - 1)
計數 = 長度 - (i * 大小);
netStream.Write(bWrite, start, count);// 將資料寫入到伺服器上
}
}
別的
netStream.Write(bWrite, 0, bWrite.Length);
}
捕獲(異常)
{
//忽略錯誤
}
}
/// <摘要>
/// 從流讀取字符
/// </摘要>
/// <param name="netStream">來自TcpClient的流</param>
/// <returns>讀取的字元</returns>
受保護的字串 ReadString(NetworkStream netStream)
{
字串 sp = null;
byte[] by = 新位元組[1024];
int size = netStream.Read(by, 0, by.Length);//讀取資料流
如果(大小 > 0)
{
sp = Encoding.Default.GetString(by);// 轉換為String
}
返回sp;
}
/// <摘要>
/// 發出指令並判斷回傳訊息是否正確
/// </摘要>
/// <param name="netStream">來自TcpClient的流</param>
/// <param name="command">指令</param>
/// <param name="state">正確的狀態碼</param>
/// <returns>是否正確</returns>
protected bool Command(NetworkStream netStream, 字串指令, 字串狀態)
{
字串 sp = null;
布爾成功=假;
嘗試
{
WriteString(netStream, command);// 寫入指令
sp = ReadString(netStream);//接受回傳訊息
if (sp.IndexOf(state) != -1)//判斷狀態碼是否正確
成功=真;
}
捕獲(異常)
{
//忽略錯誤
}
返回成功;
}
/// <摘要>
/// 字串編碼為Base64
/// </摘要>
/// <param name="str">字串</param>
/// <returns>Base64編碼的字串</returns>
受保護的字串 ToBase64(字串 str)
{
嘗試
{
byte[] by = Encoding.Default.GetBytes(str.ToCharArray());
str = Convert.ToBase64String(by);
}
捕獲(異常)
{
//忽略錯誤
}
返回字串;
}
/// <摘要>
/// 附件資訊
/// </摘要>
公共結構附件資訊
{
/// <摘要>
/// 附件的檔案名稱 [如果輸入路徑,則自動轉換為檔案名稱]
/// </摘要>
公共字串檔名
{
取得 { 返回檔案名稱; }
設定 { fileName = Path.GetFileName(value); }
} 私有字串檔名;
/// <摘要>
/// 附件的內容[由經Base64編碼的位元組組成]
/// </摘要>
公共字串位元組
{
獲取{返回位元組; }
設定 { if (值!= 位元組) 位元組 = 值; }
} 私有字串位元組;
/// <摘要>
/// 從流中讀取附件內容並建構
/// </摘要>
/// <param name="ifileName">附件的檔案名稱</param>
/// <param name="stream">流</param>
公共附件資訊(字串ifileName,流流)
{
檔案名稱 = Path.GetFileName(ifileName);
byte[] by = new byte[stream.Length];
流.Read(by, 0, (int)stream.Length); //讀取檔案內容
//格式轉換
位元組 = Convert.ToBase64String(by); // 轉換為base64編碼
}
/// <摘要>
/// 給定的位元組建構附件
/// </摘要>
/// <param name="ifileName">附件的檔案名稱</param>
/// <param name="ibytes">附件內容 [位元組]</param>
公共 AttachmentInfo(字串 ifileName, byte[] ibytes)
{
檔案名稱 = Path.GetFileName(ifileName);
位元組 = Convert.ToBase64String(ibytes); // 轉換為base64編碼
}
/// <摘要>
/// 從檔案載入並建構
/// </摘要>
/// <參數名稱=“路徑”></參數>
公共附件資訊(字串路徑)
{
檔案名稱 = Path.GetFileName(路徑);
FileStream 檔案 = new FileStream(路徑, FileMode.Open);
byte[] by = new byte[檔案長度];
file.Read(by, 0, (int)file.Length); //讀取檔案內容
//格式轉換
位元組 = Convert.ToBase64String(by); // 轉換為base64編碼
文件.關閉();
}
}