程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> c#中郵件收發處理(POP3,IMAP,SMTP)

c#中郵件收發處理(POP3,IMAP,SMTP)

編輯:.NET實例教程

本文涉及的內容:
1:自己制作Pop3Helper
   信件格式的處理有麻煩
2:使用現成的pop3類
   LumiSoft.Net.POP3.ClIEnt;
      有兩種處理方法
3:使用IMAP收郵件
      功能似乎更多,比起pop3來。
4:SMTP發送郵件
   關於 Mailbox unavailable. The server response was: 5.7.1 Unable to relay for xx 的錯誤處理

自己寫一個POP3的接收程序並不是很簡單。主要問題就是如何處理信件的格式。
其處理方法不是太復雜,用一個tcp聯接就可以了。
這是代碼
     public class Pop3Helper
    {
        string _pop3server;
        string _user;
        int _port;
        string _pwd;

        public TcpClIEnt _server;
        public NetworkStream _netStream;
        public StreamReader _reader;
        public string _data;
        public byte[] _charData;
        public string _CRLF = "\r\n";

        private string _log;
        public string LogMSG
        {
            get { return _log; }
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="server"></param>
        /// <param name="port"></param>
        /// <param name="user"></param>
        /// <param name="pwd"></param>
   &n

$False$

bsp;    public Pop3Helper(string server, int port, string user, string pwd)
        {
            _pop3server = server;
            _port = port;
            _user = user;
            _pwd = pwd;
        }
        /// <summary>
        /// connect
        /// </summary>
        public void Connect()
        {
            //create a tcp connection
            _server = new TcpClIEnt(_pop3server, _port);

            //prepare
            _netStream = _server.GetStream();
            _reader = new StreamReader(_server.GetStream());
            if (!CheckResult(_reader.ReadLine()))
                throw new Exception("Connect Error");

            //login
            _data = "USER " + this._user + _CRLF;
            _charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
            _netStream.Write(_charData, 0, _charData.Length);
            if (!CheckResult(_reader.ReadLine()))
    &nbsp;           throw new Exception("User Error");

            _data = "PASS " + this._pwd + _CRLF;
            _charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
            _netStream.Write(_charData, 0, _charData.Length);
            if (!CheckResult(_reader.ReadLine()))
                throw new Exception("Pass Error");

        }
        /// <summary>
        /// get message Numbers
        /// </summary>
        /// <returns></returns>
        public int GetMailCount()
        {
            try
            {
                _data = "STAT" + _CRLF;
                _charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
                _netStream.Write(_charData, 0, _charData.Length);
                string resp = _reader.ReadLine();
                string[] tokens = resp.Split(new char[] { '' '' });
                return Convert.ToInt32(tokens[1]);
    &nbsp;       }
            catch (Exception ex)
            {
                return 0;
            }
        }

        public string GetMail(int id)
        {
            string line;
            string content = "";
            try
            {
                //get by id
                _data = "RETR " + id + _CRLF;
                _charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
                _netStream.Write(_charData, 0, _charData.Length);
                line = _reader.ReadLine();

                if (line[0] != ''-'')
                {
                    //end with ''.''
                    while (line != ".")
                    {
    &nbsp;                   line = _reader.ReadLine();
                        content += line + "\r\n";
                    }
                }


                return content;

            }

            catch (Exception err)
            {
                Log(err.Message);
                return "Error";
            }
        }
        public void DeleteMail(int id)
        {
            _data = "DELE" + id + _CRLF;
            _charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
            _netStream.Write(_charData, 0, _charData.Length);
            if (!CheckResult(_reader.ReadLine()))
              &n throw new Exception("Delete Error");

        }
        /// <summary>
        /// close connection
        /// </summary>
        public void Close()
        {

            _data = "QUIT" + _CRLF;
            _charData = System.Text.Encoding.ASCII.GetBytes(_data.ToCharArray());
            _netStream.Write(_charData, 0, _charData.Length);

            //close
            _netStream.Close();
            _reader.Close();
        }

        private bool CheckResult(string reply)
        {
            Log(reply);
            if (reply.IndexOf("+OK") > -1)
                return true;
            else
                return false;
        }
        private void Log(string msg)
        {
            _log += msg + "\r\n";
        }
    }
。。。。。
但是這種方式的一個問題就是關於解析信件的格式。如果是附件的話,他也直接給出了二進制,不容易使用。
所以,可以使用一個現成的工具:LumiSoft.Net.POP3.ClIEnt。這裡面已經給寫好了實現,用起來也很簡單。
這是一個簡單的用法(這裡使用了兩種處理方式,前一種是不建議使用的)
。。
            using (POP3_Client pop3 = new POP3_ClIEnt())
            {
                //與Pop3服務器建立連接
  ;             pop3.Connect(_popServer, _pop3port,false);
                //驗證身份
                pop3.Authenticate(_user, _pwd, false);

                //get all messages
                POP3_MessagesInfo infos = pop3.GetMessagesInfo();
                 foreach (POP3_MessageInfo info in infos)
                {
                    byte[] bytes = pop3.GetMessage(info.MessageNumber);
                    Mime mime = Mime.Parse(bytes);
                    HandleMail(mime);
                    //delete it at last
                    //pop3.DeleteMessage(info.MessageNumber);
                }
                //the second way to do it
//for (int i = 0; i < pop3.Messages.Count; i++)
                //{
                //    byte[] bytes = pop3.Messages[i].MessageToByte();
                //    Mime mime = Mime.Parse(bytes);
                //    HandleMail(mime);
                //    //delete it at last
                //    //pop3.DeleteMessage(pop3.Messages[i].SequenceNumber);
           。。。
取得的郵件可以這要給獲得。
   #region pop3
            //string customer = mime.MainEntity.To.ToAddressListString();//cargo company
            //string sender = mime.MainEntity.From.ToAddressListString();//this is customer who send

            #endregion
            string customer = MailboxesToString(envelope.To);//cargo company
            string sender = MailboxesToString(envelope.From);//this is customer who send

。。。
除此之外,它提供的另外一個工具是IMAP,它操作起來更加方便。代碼如下:

  IMAP_Client clnt = new IMAP_ClIEnt();
            try
            {
                clnt.Connect("mail.xx.com", 143, false);
                clnt.Authenticate("user", "passWord");
                string[] folders = clnt.GetFolders();//get all types

                string folder = "Inbox";
                clnt.SelectFolder(folder);
                IMAP_SequenceSet sequence_set = new IMAP_SequenceSet();
                // All messages
                sequence_set.Parse(string.Format("{0}:{1}", 1, clnt.MessagesCount));

                IMAP_FetchItem[] fetchItems = clnt.FetchMessages(
                        sequence_set,
                        IMAP_FetchItem_Flags.UID | IMAP_FetchItem_Flags.MessageFlags | IMAP_FetchItem_Flags.Size | IMAP_FetchItem_Flags.Envelope,
                        true, false
                        );
                //int count =0;
                foreach (IMAP_FetchItem fetchItem in fetchItems)
                {
                    IMAP_Envelope envelope = fetchItem.Envelope;
                    //hanldle it, means read and search and reply
                    try
                    {
        &nbsp;               HandleMail(envelope);
                        //count++;
                    }
                    catch (Exception ex)
                    {
                        Log("Sys", ex.Message);
                    }
                }
                //delete it after hanlde
                clnt.DeleteMessages(sequence_set, false);
                //disconnect
                clnt.Disconnect();

      &nb       //MessageBox.Show(count.ToString() + " of " + fetchItems .Length+ " Success");
            }
            catch (Exception x)
            {
                Log("Sys", x.Message);
                //MessageBox.Show(x.Message);
            }
 
。。


上邊都是如何收郵件。
關於如何發送郵件是比較簡單的。這裡提供兩種方式。
第一種方式是使用網上的smtp。這種方式必須要提供用戶名和密碼。這個適合於web應用,使用的smtp也是網上的,我一般使用163的smtp,基本沒有問題。
第二種方式是使用本地的smtp。不需要提供密碼,用戶也可以是不存在的(垃圾郵件是不是就是這麼產生的?),但是必要要提供smtp端口號。
第二種方法測試的時候有時候會報錯“Mailbox unavailable. The server response was: 5.7.1 Unable to relay for xxx”,查過資料之後(在baidu上沒找到,還是google信息多一點),才發現問題原來是IIS裡SMTP服務的配置有問題。
這樣修改可以解決:到開SMTP屬性—>Access頁面?Reply Restrictions/ Reply-?Only this Below選項,加上自己的ip:127.0.0.1(允許本機,使用loalhost,如果是允許其他機器,類似設置)
代碼如下
public class EMail
    {
        static public string accountName;
        static public string passWord;
        static public string smtpServer;
        static public int smtpPort;

        /// <summary>
        /// need passWord,username, smtpserver
        /// </summary>
        /// <param name="to"></param>
        /// <param name="subject"></param>
        /// <param name="body"></param>
        static public void SendMail(string sendTo, string subject, string body)
        {
            //.Net smtp
            System.Web.Mail.MailMessage mailmsg = new System.Web.Mail.MailMessage();
            mailmsg.To = sendTo;
            //mailmsg.Cc = cc;
            mailmsg.Subject = subject;
            mailmsg.Body = body;

            //sender here
            mailmsg.From = EMail.accountName;
            // certify needed 
            mailmsg.FIElds.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");//1 is to certify
            //the user id  
            mailmsg.FIElds.Add(
                "http://schemas.microsoft.com/cdo/configuration/sendusername",
                EMail.accountName);
             //the passWord
            mailmsg.FIElds.Add(
                "http://schemas.microsoft.com/cdo/configuration/sendpassWord",
                 EMail.passWord);

            System.Web.Mail.SmtpMail.SmtpServer = EMail.smtpServer;
            System.Web.Mail.SmtpMail.Send(mailmsg);

        }


        #region send mail2
        /// <summary>
        /// need username,smtp,smtp port
        /// </summary>
        /// <param name="sendTo"></param>
        /// <param name="subject"></param>
        /// <param name="body"></param>
        static public void SendMail2(string sendTo,string subject, string body)
  &nbs   {
            System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
            msg.To.Add(sendTo);
            msg.From = new System.Net.Mail.MailAddress(accountName );

            msg.Subject = subject;
            msg.SubjectEncoding = System.Text.Encoding.UTF8;
            msg.Body = body;//
            msg.BodyEncoding = System.Text.Encoding.UTF8;
            msg.IsBodyHtml = false;
            //msg.Priority = MailPriority.High;//

            System.Net.Mail.SmtpClient clIEnt = new System.Net.Mail.SmtpClIEnt();
            clIEnt.Host = smtpServer;
            clIEnt.Port = smtpPort;
            //clIEnt.Credentials = new System.Net.NetworkCredential("[email protected]", "pass");
            clIEnt.Send(msg);

        }
        #endregion

    }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved