• c#中邮件收发处理(POP3,IMAP,SMTP)


    c#中邮件收发处理(POP3,IMAP,SMTP)

    Posted on 2007-10-18 12:45 随心所欲 阅读(909) 评论(17)  编辑  收藏 所属分类: 通讯/WebServer

    本文涉及的内容:
    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>
            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()))
                    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]);
                }
                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 != ".")
                        {
                            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()))
                    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
                        {
                            HandleMail(envelope);
                            //count++;
                        }
                        catch (Exception ex)
                        {
                            Log("Sys", ex.Message);
                        }
                    }
                    //delete it after hanlde
                    clnt.DeleteMessages(sequence_set, false);
                    //disconnect
                    clnt.Disconnect();

                    //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)
            {
                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("user@xxx.com", "pass");
                client.Send(msg);

            }
            #endregion

        }

  • 相关阅读:
    php-beanstalkd消息队列类分享
    php curl抓取类分享
    df -i 100%时处理方法
    php生成红包
    PHP牛牛游戏算法
    Yii 框架不同逻辑处理方法统一事务处理
    Linux上web服务器搭建
    Linux 上pcntl安装步骤
    PHP错误级别设置
    day40 ,epoll,数据库相关概念
  • 原文地址:https://www.cnblogs.com/smallfa/p/929962.html
Copyright © 2020-2023  润新知