C#开发邮件收发(同步)

发邮件界面:

收邮件界面:

先分析邮件发送类

邮件发送类使用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);
            }
        }
    }
}

 

 收邮件的代码:

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("删除成功");
        }
    }
}

 

posted @ 2019-03-09 10:42  冯六万  阅读(5869)  评论(2编辑  收藏  举报