發郵件界面:html
收郵件界面:安全
先分析郵件發送類服務器
郵件發送類使用smtp協議,這裏以QQ郵箱爲例網絡
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; //添加的命名空間引用 using System.Net; using System.Net.Mail; using System.IO; using System.Net.Mime; namespace SendMailExample { public partial class FormSendMail : Form { public FormSendMail() { InitializeComponent(); } private void FormSendMail_Load(object sender, EventArgs e) { //郵箱協議 textBoxSmtpServer.Text = "smtp.qq.com"; //發送人郵箱 textBoxSend.Text = "郵箱帳號"; //發送人姓名 textBoxDisplayName.Text = "名字"; //密碼 textBoxPassword.Text = "郵箱密碼"; //收件人姓名 textBoxReceive.Text = "收件人郵箱帳號"; //發送標題 textBoxSubject.Text = "測試mytest"; //發送內容 textBoxBody.Text = "This is a test(測試)"; radioButtonSsl.Checked = true; } //單擊【發送】按鈕觸發的事件 private void buttonSend_Click(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; //實例化一個發送郵件類 MailMessage mailMessage = new MailMessage(); //發件人郵箱,方法重載不一樣,能夠根據需求自行選擇 mailMessage.From = new MailAddress(textBoxSend.Text, textBoxDisplayName.Text, System.Text.Encoding.UTF8); //收件人郵箱地址 mailMessage.To.Add(textBoxReceive.Text); //郵件標題 mailMessage.Subject = textBoxSubject.Text; //郵件發送使用的編碼 mailMessage.SubjectEncoding = System.Text.Encoding.Default; //郵件發送的內容 mailMessage.Body = textBoxBody.Text; //發送郵件的標題 mailMessage.BodyEncoding = System.Text.Encoding.Default; //指定郵件是否爲html格式 mailMessage.IsBodyHtml = false; //設置電子郵件的優先級 mailMessage.Priority = MailPriority.Normal; //添加附件 Attachment attachment = null; if (listBoxFileName.Items.Count > 0) { for (int i = 0; i < listBoxFileName.Items.Count; i++) { string pathFileName = listBoxFileName.Items[i].ToString(); string extName = Path.GetExtension(pathFileName).ToLower(); //這裏僅舉例說明如何判斷附件類型 if (extName == ".rar" || extName == ".zip") { attachment = new Attachment(pathFileName, MediaTypeNames.Application.Zip); } else { attachment = new Attachment(pathFileName, MediaTypeNames.Application.Octet); } ContentDisposition cd = attachment.ContentDisposition; cd.CreationDate = File.GetCreationTime(pathFileName); cd.ModificationDate = File.GetLastWriteTime(pathFileName); cd.ReadDate = File.GetLastAccessTime(pathFileName); mailMessage.Attachments.Add(attachment); } } SmtpClient smtpClient = new SmtpClient(); smtpClient.Host = textBoxSmtpServer.Text; smtpClient.Port = 25; //是否使用安全套接字層加密鏈接 smtpClient.EnableSsl = radioButtonSsl.Checked; //不使用默認憑證,注意此句必須放在client.Credentials的上面 smtpClient.UseDefaultCredentials = false; smtpClient.Credentials = new NetworkCredential(textBoxSend.Text, textBoxPassword.Text); //郵件經過網絡直接發送到服務器 smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network; try { smtpClient.Send(mailMessage); MessageBox.Show("發送成功"); } catch (SmtpException smtpError) { MessageBox.Show("發送失敗:" + smtpError.StatusCode + "\n\n" + smtpError.Message + "\n\n" + smtpError.StackTrace); } finally { mailMessage.Dispose(); smtpClient = null; this.Cursor = Cursors.Default; } } //單擊【添加附件】按鈕觸發的事件 private void buttonAddAttachment_Click(object sender, EventArgs e) { //提示用戶打開一個文件夾 OpenFileDialog myOpenFileDialog = new OpenFileDialog(); myOpenFileDialog.CheckFileExists = true; //只接收有效的文件名 myOpenFileDialog.ValidateNames = true; //容許一次選擇多個文件做爲附件 myOpenFileDialog.Multiselect = true; myOpenFileDialog.ShowDialog(); if (myOpenFileDialog.FileNames.Length > 0) { listBoxFileName.Items.AddRange(myOpenFileDialog.FileNames); } } } }
收郵件的代碼:tcp
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; //添加的命名空間引用 using System.Net; using System.Net.Sockets; using System.IO; namespace ReceiveMailExample { public partial class FormReceiveMail : Form { private TcpClient tcpClient; private NetworkStream networkStream; private StreamReader sr; private StreamWriter sw; public FormReceiveMail() { InitializeComponent(); textBoxPOP3Server.Text = "pop.qq.com"; textBoxPassword.Text = "密碼"; textBoxUser.Text = "郵箱帳號"; } //單擊創建鏈接按鈕觸發的事件 private void buttonConnect_Click(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; listBoxStatus.Items.Clear(); try { //創建與POP3服務器的鏈接,使用默認端口110 tcpClient = new TcpClient(textBoxPOP3Server.Text,110); listBoxStatus.Items.Add("與pop3服務器鏈接成功"); } catch { MessageBox.Show("與服務器鏈接失敗"); return; } string str; networkStream = tcpClient.GetStream(); //獲得輸入流 sr = new StreamReader(networkStream, Encoding.Default); //獲得輸出流 sw = new StreamWriter(networkStream, Encoding.Default); sw.AutoFlush = true; //讀取服務器回送的鏈接信息 str = GetResponse(); if (CheckResponse(str) == false) return; //向服務器發送用戶名,請求確認 SendToServer("USER " + textBoxUser.Text); str = GetResponse(); if (CheckResponse(str) == false) return; //向服務器發送密碼,請求確認 SendToServer("PASS " + textBoxPassword.Text); str = GetResponse(); if (CheckResponse(str) == false) return; //向服務器發送LIST命令,請求獲取郵件總數和總字節數 SendToServer("LIST"); str = GetResponse(); if (CheckResponse(str) == false) return; string[] splitString = str.Split(' '); //從字符串中取子串獲取郵件總數 int count = int.Parse(splitString[1]); //判斷郵箱中是否有郵件 if (count > 0) { listBoxOperation.Items.Clear(); groupBoxOperation.Text = "信箱中共有 " + splitString[1] + " 封郵件"; //向郵件列表框中添加郵件 for (int i = 0; i < count; i++) { str = GetResponse(); splitString = str.Split(' '); listBoxOperation.Items.Add(string.Format( "第{0}封:{1}字節", splitString[0], splitString[1])); } listBoxOperation.SelectedIndex = 0; //讀出結束符 str = GetResponse(); //設置對應狀態信息 buttonRead.Enabled = true; buttonDelete.Enabled = true; } else { groupBoxOperation.Text = "信箱中沒有郵件"; buttonRead.Enabled = false; buttonDelete.Enabled = false; } buttonConnect.Enabled = false; buttonDisconnect.Enabled = true; Cursor.Current = Cursors.Default; } private bool SendToServer(string str) { try { sw.WriteLine(str); sw.Flush(); listBoxStatus.Items.Add("發送:" + str); return true; } catch (Exception err) { listBoxStatus.Items.Add("發送失敗:" + err.Message); return false; } } private string GetResponse() { string str = null; try { str = sr.ReadLine(); if (str == null) { listBoxStatus.Items.Add("收到:null"); } else { listBoxStatus.Items.Add("收到:" + str); if (str.StartsWith("-ERR")) { str = null; } } } catch (Exception ex) { listBoxStatus.Items.Add("接收失敗:" + ex.Message); } return str; } private bool CheckResponse(string responseString) { if (responseString == null) { return false; } else { if (responseString.StartsWith("+OK")) { return true; } else { return false; } } } //單擊斷開鏈接按鈕觸發的事件 private void buttonDisconnect_Click(object sender, EventArgs e) { SendToServer("QUIT"); sr.Close(); sw.Close(); networkStream.Close(); tcpClient.Close(); listBoxOperation.Items.Clear(); richTextBoxOriginalMail.Clear(); listBoxStatus.Items.Clear(); groupBoxOperation.Text = "郵件信息"; buttonConnect.Enabled = true; buttonDisconnect.Enabled = false; } //單擊閱讀信件按鈕觸發的事件 private void buttonRead_Click(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; richTextBoxOriginalMail.Clear(); string mailIndex = listBoxOperation.SelectedItem.ToString(); mailIndex = mailIndex.Substring(1, mailIndex.IndexOf("封") - 1); SendToServer("RETR " + mailIndex); string str = GetResponse(); if (CheckResponse(str) == false) return; try { string receiveData = sr.ReadLine(); if (receiveData.StartsWith("-ERR") == true) { listBoxStatus.Items.Add(receiveData); } else { while (receiveData != ".") { richTextBoxOriginalMail.AppendText(receiveData + "\r\n"); receiveData = sr.ReadLine(); } } } catch (InvalidOperationException err) { listBoxStatus.Items.Add("Error: " + err.ToString()); } Cursor.Current = Cursors.Default; } private void DecodeMailHeader(string mail) { string header = ""; int pos = mail.IndexOf("\n\n"); if (pos == -1) { header = GetDecodedHeader(mail); } else { header = mail.Substring(0, pos + 2); } //richTextBoxDecode.AppendText(GetDecodedHeader(header)); } private string GetDecodedHeader(string header) { StringBuilder s = new StringBuilder(); s.AppendLine("Subject:" + GetEncodedValueString(header, "Subject: ", false)); s.AppendLine("From:" + GetEncodedValueString(header, "From: ", false).Trim()); s.AppendLine("To:" + GetEncodedValueString(header, "To: ", true).Trim()); s.AppendLine("Date:" + GetDateTimeFromString(GetValueString(header, "Date: ", false, false))); s.AppendLine("Cc:" + GetEncodedValueString(header, "Cc: ", true).Trim()); s.AppendLine("ContentType:" + GetValueString(header, "Content-Type: ", false, true)); return s.ToString(); } /// <summary> /// 把時間轉成字符串形式 /// </summary> /// <param name="DateTimeString"></param> /// <returns></returns> private string GetDateTimeFromString(string DateTimeString) { if (DateTimeString == "") { return null; } try { string strDateTime; if (DateTimeString.IndexOf("+") != -1) { strDateTime = DateTimeString.Substring(0, DateTimeString.IndexOf("+")); } else if (DateTimeString.IndexOf("-") != -1) { strDateTime = DateTimeString.Substring(0, DateTimeString.IndexOf("-")); } else { strDateTime = DateTimeString; } DateTime dt = DateTime.Parse(strDateTime); return dt.ToString(); } catch { return null; } } private string GetEncodedValueString(string SourceString, string Key, bool SplitBySemicolon) { int j; string strValue; string strSource = SourceString.ToLower(); string strReturn = ""; j = strSource.IndexOf(Key.ToLower()); if (j != -1) { j += Key.Length; int kk = strSource.IndexOf("\n", j); strValue = SourceString.Substring(j, kk - j).TrimEnd(); do { if (strValue.IndexOf("=?") != -1) { if (SplitBySemicolon == true) { strReturn += ConvertStringEncodingFromBase64(strValue) + "; "; } else { strReturn += ConvertStringEncodingFromBase64(strValue); } } else { strReturn += strValue; } j += strValue.Length + 2; if (strSource.IndexOf("\r\n", j) == -1) { break; } else { strValue = SourceString.Substring(j, strSource.IndexOf("\r\n", j) - j).TrimEnd(); } } while (strValue.StartsWith(" ") || strValue.StartsWith("\t")); } else { strReturn = ""; } return strReturn; } private string GetValueString(string SourceString, string Key, bool ContainsQuotationMarks, bool ContainsSemicolon) { int j; string strReturn; string strSource = SourceString.ToLower(); j = strSource.IndexOf(Key.ToLower()); if (j != -1) { j += Key.Length; strReturn = SourceString.Substring(j, strSource.IndexOf("\n", j) - j).TrimStart().TrimEnd(); if (ContainsSemicolon == true) { if (strReturn.IndexOf(";") != -1) { strReturn = strReturn.Substring(0, strReturn.IndexOf(";")); } } if (ContainsQuotationMarks == true) { int i = strReturn.IndexOf("\""); int k; if (i != -1) { k = strReturn.IndexOf("\"", i + 1); if (k != -1) { strReturn = strReturn.Substring(i + 1, k - i - 1); } else { strReturn = strReturn.Substring(i + 1); } } } return strReturn; } else { return ""; } } private string ConvertStringEncodingFromBase64(string SourceString) { try { if (SourceString.IndexOf("=?") == -1) { return SourceString; } else { int i = SourceString.IndexOf("?"); int j = SourceString.IndexOf("?", i + 1); int k = SourceString.IndexOf("?", j + 1); char chrTransEnc = SourceString[j + 1]; switch (chrTransEnc) { case 'B': return ConvertStringEncodingFromBase64Ex(SourceString.Substring(k + 1, SourceString.IndexOf("?", k + 1) - k - 1), SourceString.Substring(i + 1, j - i - 1)); default: throw new Exception("unhandled content transfer encoding"); } } } catch { return ""; } } /// <summary> /// 把Base64編碼轉換成字符串 /// </summary> /// <param name="SourceString"></param> /// <param name="Charset"></param> /// <returns></returns> private string ConvertStringEncodingFromBase64Ex(string SourceString, string Charset) { try { Encoding enc; if (Charset == "") enc = Encoding.Default; else enc = Encoding.GetEncoding(Charset); return enc.GetString(Convert.FromBase64String(SourceString)); } catch { return ""; } } /// <summary> /// 把字符串轉換成Base64Ex編碼 /// </summary> /// <param name="SourceString"></param> /// <param name="Charset"></param> /// <param name="AutoWordWrap"></param> /// <returns></returns> private string ConvertStringEncodingToBase64Ex(string SourceString, string Charset, bool AutoWordWrap) { Encoding enc = Encoding.GetEncoding(Charset); byte[] buffer = enc.GetBytes(SourceString); string strContent = Convert.ToBase64String(buffer); StringBuilder strTemp = new StringBuilder(); int ii = 0; for (int i = 0; i <= strContent.Length / 76 - 1; i++) { strTemp.Append(strContent.Substring(76 * i, 76) + "\r\n"); ii++; } strTemp.Append(strContent.Substring(76 * (ii))); strContent = strTemp.ToString(); return strContent; } private string ConvertStringEncoding(string SourceString, string Charset) { try { Encoding enc; if (Charset == "8bit" || Charset == "") { enc = Encoding.Default; } else { enc = Encoding.GetEncoding(Charset); } return enc.GetString(Encoding.ASCII.GetBytes(SourceString)); } catch { return Encoding.Default.GetString(Encoding.ASCII.GetBytes(SourceString)); } } //單擊刪除信件按鈕觸發的事件 private void buttonDelete_Click(object sender, EventArgs e) { string parameter = listBoxOperation.SelectedItem.ToString(); parameter = parameter.Substring(1, parameter.IndexOf("封") - 1); SendToServer("DELE " + parameter); string str = GetResponse(); if (CheckResponse(str) == false) return; richTextBoxOriginalMail.Clear(); int j = listBoxOperation.SelectedIndex; listBoxOperation.Items.Remove(listBoxOperation.Items[j].ToString()); MessageBox.Show("刪除成功"); } } }