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

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

本文涉及的内容:
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; } } ///

/// /// /// /// /// /// public Pop3Helper(string server, int port, string user, string pwd) { _pop3server = server; _port = port; _user = user; _pwd = pwd; } /// /// connect /// 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"); } /// /// get message Numbers /// /// 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"); } /// /// close connection /// 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; ///

/// need password,username, smtpserver /// /// /// /// 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 /// /// need username,smtp,smtp port /// /// /// /// 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("[email protected]", "pass"); client.Send(msg); } #endregion }   

 

 

 

 

 

你可能感兴趣的:(C#网络核心编程)