您的位置:首页 > 运维架构

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

2007-10-19 09:58 543 查看


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

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: