本文涉及的內容:
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
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()))
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()))
&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
{
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);
}
。。
/// <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);
}
msg.Subject = subject; System.Net.Mail.SmtpClient clIEnt = new System.Net.Mail.SmtpClIEnt(); } }
#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.SubjectEncoding = System.Text.Encoding.UTF8;
msg.Body = body;//
msg.BodyEncoding = System.Text.Encoding.UTF8;
msg.IsBodyHtml = false;
//msg.Priority = MailPriority.High;//
clIEnt.Host = smtpServer;
clIEnt.Port = smtpPort;
//clIEnt.Credentials = new System.Net.NetworkCredential("[email protected]", "pass");
clIEnt.Send(msg);
#endregion