//////////////////////////////////////////////////// // Public Properties /// <summary> /// Returns "true" if the message conntains MIME attachments. /// </summary> /// <res>Attachments are determined based on the Content-Type of the message.</res> public bool HasAttachments { get { return m_bAttachments; } } /// <summary> /// Date the message was received. /// </summary> public string Date { get { return m_strMsgDate; } } /// <summary> /// Byte array representing the decoded body of an attachment. /// </summary> /// <res>Only available if the entity is an attachment.</res> public byte[] Attachment { get { return getByteData(); } } /// <summary> /// Date the message was received. /// </summary> public string ContentType { get { return m_strContType; } } /// <summary> /// Comma-separated list of all recipients. /// </summary> public string Recipient { get { string _temp = null; for(int i = 0; i < m_recRecipients.Length; i++) { _temp += m_recRecipients[i].m_strRecipient; if(i != m_recRecipients.Length - 1) _temp += ", "; } return _temp; } } /// <summary> /// The message's "From:" field. /// </summary> public string Sender { get { return m_strSender; } } /// <summary> /// The message's "Subject:" field. /// </summary> public string Subject { get { return m_strSubject; } } /// <summary> /// If the message has an attachment, but is not /// MIME encoded, this is the name of the attachemt /// </summary> public string FileName { get { return m_strFileName; } } /// <summary> /// The MIME Content-Dispostion of the message /// </summary> /// <res> /// If the message contains one attachment and no message text, /// this value will be "attachment". /// </res> public string Disposition { get { return m_strDisposition; } } /// <summary> /// The name associated with message's "Reply-To:" field. /// </summary> public string ReplyTo { get { return m_strReplyTo; } } /// <summary> /// The address associated with message's "Reply-To:" field. /// </summary> public string ReplyToAddress { get { return m_strReplyToAddress; } } /// <summary> /// The complete header of the message. /// </summary> public string HeaderString { get { return m_strHeader; } } /// <summary> /// The size (in octets) of the message. /// </summary> public int Size { get { return m_nSize; } }
/// <summary> /// The message's ID on the server. /// </summary> public string ID { get { return m_strID; } } /// <summary> /// The index of the message in the SAPOP3 collection. /// </summary> public int Index { get { return m_nIndex; } } /// <summary> /// The message's UID on the server. /// </summary> public string UID { get { return m_strUID; } } /// <summary> /// The text of the message. /// </summary> /// <res>If the message is MIME-encoded, the client should iterate the SAMimeEntity /// collection for the first with Content-Type of "text/plain".</res> public string Text { get { return m_strMsgText; } }
第二部分如下:接上面代码 ---------------------------------------------------------------------------- /// Number of SAMime entities associated with the message. /// </summary> public int MimeEntities { get { return m_nMIMECount; } } // Implementation of IEnumerable public IEnumerator GetEnumerator() { return new MimeEnumPvt(this); } // enumerator nested class private class MimeEnumPvt : IEnumerator { private int pos = -1; private SAPOP3Message _message; public MimeEnumPvt(SAPOP3Message _message) { this._message = _message; } public bool MoveNext() { if(pos < _message.m_nMIMECount - 1) { pos++; return true; } else return false; } public void Reset() { pos = -1; } public SAMimeEntity Current { get { return (SAMimeEntity)_message.m_mimeEntity[pos];
breader = new BinaryReader(fstream); // _filelength.ToInt32(); return breader.ReadBytes(Convert.ToInt32(_filelength));
} catch(Exception e) { string err = e.Message; string exp = e.ToString(); int i = 0; return null; } finally { if(breader != null) breader.Close(); if(fstream != null) fstream.Close(); } } /////////////////////////////////////////////////// // parsing functions internal string GetTextMessage(string Buffer, int MessageIndex) { int end, begin; begin = end = 0; try { if(m_strContType.IndexOf("digest") >= 0) { // this is a digest method ParseDigestMessage(Buffer, MessageIndex); } else { // find "\r\n\r\n" denoting end of header if((begin = Buffer.IndexOf("\r\n\r\n")) < 0) throw new POP3ParseException("GetMessageText could not find end of header"); // find end of text // if((end = Buffer.LastIndexOfAny(NON_WHITE.ToCharArray())) < 0) if((end = Buffer.LastIndexOfAny(ALPHABET.ToCharArray())) < 0) throw new POP3ParseException("GetMessageText could not find end of message text"); begin += 4; m_strMsgText = Buffer.Substring(begin, end - begin + 1); } } catch(Exception e) { m_pSAPOP3.TRACE(e.ToString()); if(m_pSAPOP3.Log) { string strErr = "SAPOP3Message::GetTextMessage()"; strErr += e.Message; m_pSAPOP3.LogError(strErr); } } return null; } internal bool ParseMixedMessage(string Buffer, int MessageIndex) {
m_nMIMECount = 0; try { int end, begin, pos; end = begin = pos = 0; while((begin = Buffer.IndexOf(m_strBoundary, pos)) >= 0) { pos = begin + 1; if((end = Buffer.IndexOf(m_strBoundary, pos)) < 0) { // make we're at the end of the buffer if(Buffer.Substring((begin + m_strBoundary.Length), 2) == "--") { return true; } else throw new POP3ParseException("Could not find boundary"); }
// we want to find the same boundary at the next loop pos++; // remove boundary from buffer begin += m_strBoundary.Length; m_mimeEntity.Add(new SAMimeEntity(m_pSAPOP3, Buffer.Substring(begin, end - begin)));
ProcessMIMEEntity((SAMimeEntity)m_mimeEntity[m_nMIMECount]); // set index ((SAMimeEntity)m_mimeEntity[m_nMIMECount]).m_nIndex = m_nMIMECount; m_nMIMECount++;
我曾经做过类似的软件,信息在传输过程中,我采用的是UTF-8方式发送的编码,并且在客/服端均用相同的编码方式接收和发送,BASE64编码时也没有出过什么问题,你可以说详细一点,好让大家为你解答
你是用的Convert.FromBase64(string)吗?
能具体点吗?
有兴趣给我发端消息,留个MSN.
能给我发一个吗?
[email protected]
我也想要个
[email protected]
private MailMessage aa; //body可以编码,可是我不太懂
aa.To=textBox1.Text;
aa.Cc=textBox2.Text;
aa.Bcc=textBox3.Text;
aa.From=textBox4.Text;
aa.Subject=textBox5.Text;
aa.Body=richTextBox1.Text;
你说的utf-8是怎么实现的?另外,接受的时候还用不用转换了?
谢谢指教
/// </summary>
public class SMTPMail
{
/// <summary>
/// 错误反馈信息
/// </summary>
private string strErrMessage = null; /// <summary>
/// SMTP服务器反馈的信息
/// </summary>
private string strResponse; /// <summary>
/// 构造函数
/// </summary>
public SMTPMail()
{
strErrMessage = "";
strResponse = "";
} /// <summary>
/// 取得错误反馈信息
/// </summary>
public string ErrorMessage
{
get
{
return strErrMessage ;
}
} /// <summary>
/// 取得SMTP服务器反馈的信息
/// </summary>
public string ServerResponse
{
get
{
return strResponse;
}
} /// <summary>
/// 邮件发送优先级
/// </summary>
public enum Prioritys
{
/// <summary>
/// 最高级别
/// </summary>
HIGH = 1,
/// <summary>
/// 默认级别
/// </summary>
NORMAL = 3,
/// <summary>
/// 最低级别
/// </summary>
LOW = 5
} public void SendMail(string SmtpHost,int Port,string From,string DisplayFromName,string To,string DisplayToName,Prioritys Priority,bool Html,string Base,string Subject,string Message)
{
try
{
string strResponseNumber;
SMTPClient smtpcMail = new SMTPClient();
smtpcMail.Connect(SmtpHost,Port);
bool bolConnect = smtpcMail.isConnected(); //判断是否进行了连接
if (!bolConnect)
{
strErrMessage = "Smtp服务器连接失败...";
return;
} //读取反馈信息
strResponseNumber = smtpcMail.GetServerResponse();
if (smtpcMail.DoesStringContainSMTPCode(strResponseNumber,"220"))
{
this.strResponse += strResponseNumber;
}
else
{
this.strErrMessage = "连接失败" + strResponseNumber;
return ;
} string[] strSendBuffer = new string[6];
string[] strResponseCode = {"220","250","251","354","221"}; // success codes from SMTP server string strData = "";
strData = string.Concat("HELO ",SmtpHost);
strData = string.Concat(strData,"\r\n");
strSendBuffer[0] = strData ; strData = "";
strData = string.Concat("MAIL FROM: ","<" + From + ">");
strData = string.Concat(strData,"\r\n");
strSendBuffer[1] = strData; strData = "";
strData = string.Concat("RCPT TO: ","<" + To + ">");
strData = string.Concat(strData,"\r\n");
strSendBuffer[2] = strData; strData = "" ;
strData = string.Concat("DATA","\r\n");
strSendBuffer[3] = strData ; strData = "" ;
strData = string.Concat("From: ",DisplayFromName + "<" + From + ">");
strData = string.Concat(strData,"\r\n" );
strData = string.Concat(strData,"To: " );
strData = string.Concat(strData,DisplayToName + "<" + To + ">");
strData = string.Concat(strData,"\r\n" );
strData = string.Concat(strData,"Subject: " );
strData = string.Concat(strData,Subject);
strData = string.Concat(strData,"\r\n");
strData = string.Concat(strData,"MIME-Version: 1.0" );
strData = string.Concat(strData,"\r\n");
strData = string.Concat(strData,"X-Priority: " + Priority);
strData = string.Concat(strData,"\r\n");
strData = string.Concat(strData,"X-MSMail-Priority: " + Priority);
strData = string.Concat(strData,"\r\n");
if(Html == true)
{
strData = string.Concat(strData,"Content-Type: text/html;" );
}
else
{
strData = string.Concat(strData,"Content-Type: text/plain;" );
}
strData = string.Concat(strData,"\r\n");
strData = string.Concat(strData,"charset=\"iso-8859-1\"" );
strData = string.Concat(strData,"\r\n");
if(Html == true)
{
strData = string.Concat(strData,"Content-Transfer-Encoding: text/html;" );
}
else
{
strData = string.Concat(strData,"Content-Transfer-Encoding: text/plain;" );
}
strData = string.Concat(strData,"\r\n");
strData = string.Concat(strData,"Content-Base: \"" + Base + "\"" );
strData = string.Concat(strData,"\r\n" + "\r\n"); strData = string.Concat(strData,Message);
strData = string.Concat(strData,"\r\n.\r\n");
strSendBuffer[4] = strData; strData = "" ;
strData = string.Concat(strData,"QUIT\r\n");
strSendBuffer[5] = strData; int i = 0 ; while(i < strSendBuffer.Length)
{
smtpcMail.SendCommandToServer(strSendBuffer[i]);
strResponseNumber = smtpcMail.GetServerResponse(); for(int j=0;j<strResponseCode.Length;j++)
{
if (smtpcMail.DoesStringContainSMTPCode(strResponseNumber,strResponseCode[j]))
{
this.strResponse += strResponseNumber;
this.strResponse += "";
break;
}
else
{
if(j==strResponseCode.Length-1)
{
this.strErrMessage += strResponseNumber;
this.strErrMessage += strSendBuffer[i];
return;
}
}
} i++ ;
} // 结束循环
}
catch(SocketException err)
{
this.strErrMessage += err.Message + " " + err.StackTrace;
}
catch(Exception e)
{
this.strErrMessage += e.Message + " " + e.StackTrace;
}
} //结束邮件发送方法 } // 结束类
{
internal bool m_bDeleted;
internal bool m_bCached;
internal string m_strUID;
internal int m_nSize;
internal string m_strTempDir = "C:\\temp\\";
internal int m_nIndex = 0;
internal bool m_bAttachments;
internal int m_nMIMECount = 0; // number of MIME entities
internal ArrayList m_mimeEntity;
internal string m_strMimeVer;
internal string m_strID;
internal string m_strBoundary;
internal string m_strReplyTo;
internal string m_strReplyToAddress;
internal string m_strMsgText;
internal SAPOP3 m_pParent = null;
// constructor
public SAPOP3Message(SAPOP3 sapop3, string TempDirectory) : base(sapop3)
{
m_pParent = sapop3;
m_mimeEntity = new ArrayList();
m_bDeleted = false;
}
////////////////////////////////////////////
// Indexer
/// <summary>
/// Indexer. Allows [] operator to access SAMimeEntity objects contained within the message
/// </summary>
public SAMimeEntity this[int index]
{
get
{
return (SAMimeEntity)m_mimeEntity[index];
}
} // OVERRIDES
public override string ToString()
{
StringBuilder tmp = new StringBuilder();
tmp.Append("\n\nSAPOP3Message:");
tmp.Append("\nCharset: ");
tmp.Append(m_strCharset);
tmp.Append("\nContType: ");
tmp.Append(m_strContType);
tmp.Append("\nDisposition: ");
tmp.Append(m_strDisposition);
tmp.Append("\nSender: ");
tmp.Append(m_strSender);
tmp.Append("\nSubject: ");
tmp.Append( m_strSubject);
tmp.Append("\nMsgDate: ");
tmp.Append( m_strMsgDate);
tmp.Append( "\nRecipients: ");
if(m_recRecipients != null)
{
foreach(Recipient rec in m_recRecipients)
{
tmp.Append(rec.ToString());
}
}
tmp.Append("\nIsAttachment: ");
tmp.Append( m_bIsAttachment.ToString());
tmp.Append( "\nEncoding: ");
tmp.Append( m_strEncoding); return tmp.ToString();
}
////////////////////////////////////////////////////
// Public Properties /// <summary>
/// Returns "true" if the message conntains MIME attachments.
/// </summary>
/// <res>Attachments are determined based on the Content-Type of the message.</res>
public bool HasAttachments
{
get
{
return m_bAttachments;
}
}
/// <summary>
/// Date the message was received.
/// </summary>
public string Date
{
get
{
return m_strMsgDate;
}
}
/// <summary>
/// Byte array representing the decoded body of an attachment.
/// </summary>
/// <res>Only available if the entity is an attachment.</res>
public byte[] Attachment
{
get
{
return getByteData();
}
}
/// <summary>
/// Date the message was received.
/// </summary>
public string ContentType
{
get
{
return m_strContType;
}
}
/// <summary>
/// Comma-separated list of all recipients.
/// </summary>
public string Recipient
{
get
{
string _temp = null;
for(int i = 0; i < m_recRecipients.Length; i++)
{
_temp += m_recRecipients[i].m_strRecipient;
if(i != m_recRecipients.Length - 1)
_temp += ", ";
}
return _temp;
}
}
/// <summary>
/// The message's "From:" field.
/// </summary>
public string Sender
{
get
{
return m_strSender;
}
}
/// <summary>
/// The message's "Subject:" field.
/// </summary>
public string Subject
{
get
{
return m_strSubject;
}
}
/// <summary>
/// If the message has an attachment, but is not
/// MIME encoded, this is the name of the attachemt
/// </summary>
public string FileName
{
get
{
return m_strFileName;
}
}
/// <summary>
/// The MIME Content-Dispostion of the message
/// </summary>
/// <res>
/// If the message contains one attachment and no message text,
/// this value will be "attachment".
/// </res>
public string Disposition
{
get
{
return m_strDisposition;
}
}
/// <summary>
/// The name associated with message's "Reply-To:" field.
/// </summary>
public string ReplyTo
{
get
{
return m_strReplyTo;
}
}
/// <summary>
/// The address associated with message's "Reply-To:" field.
/// </summary>
public string ReplyToAddress
{
get
{
return m_strReplyToAddress;
}
}
/// <summary>
/// The complete header of the message.
/// </summary>
public string HeaderString
{
get
{
return m_strHeader;
}
}
/// <summary>
/// The size (in octets) of the message.
/// </summary>
public int Size
{
get
{
return m_nSize;
}
}
/// <summary>
/// The message's ID on the server.
/// </summary>
public string ID
{
get
{
return m_strID;
}
}
/// <summary>
/// The index of the message in the SAPOP3 collection.
/// </summary>
public int Index
{
get
{
return m_nIndex;
}
}
/// <summary>
/// The message's UID on the server.
/// </summary>
public string UID
{
get
{
return m_strUID;
}
}
/// <summary>
/// The text of the message.
/// </summary>
/// <res>If the message is MIME-encoded, the client should iterate the SAMimeEntity
/// collection for the first with Content-Type of "text/plain".</res>
public string Text
{
get
{
return m_strMsgText;
}
}
----------------------------------------------------------------------------
/// Number of SAMime entities associated with the message.
/// </summary>
public int MimeEntities
{
get
{
return m_nMIMECount;
}
}
// Implementation of IEnumerable
public IEnumerator GetEnumerator()
{
return new MimeEnumPvt(this);
}
// enumerator nested class
private class MimeEnumPvt : IEnumerator
{
private int pos = -1;
private SAPOP3Message _message; public MimeEnumPvt(SAPOP3Message _message)
{
this._message = _message;
}
public bool MoveNext()
{
if(pos < _message.m_nMIMECount - 1)
{
pos++;
return true;
}
else
return false;
}
public void Reset()
{
pos = -1;
}
public SAMimeEntity Current
{
get
{
return (SAMimeEntity)_message.m_mimeEntity[pos];
}
}
object IEnumerator.Current
{
get
{
return _message.m_mimeEntity[pos];
}
} };
////////////////////////////////////////////////////////
// Private Methods
private byte[] getByteData()
{
FileStream fstream = null;
FileInfo tempfile = null;
BinaryReader breader = null;
try
{
// read string from temp file
tempfile = new FileInfo(m_strTempFile);
long _filelength = tempfile.Length;
tempfile = null;
fstream = new FileStream(m_strTempFile, FileMode.Open, FileAccess.Read);
breader = new BinaryReader(fstream); // _filelength.ToInt32();
return breader.ReadBytes(Convert.ToInt32(_filelength));
}
catch(Exception e)
{
string err = e.Message;
string exp = e.ToString();
int i = 0;
return null;
}
finally
{
if(breader != null)
breader.Close();
if(fstream != null)
fstream.Close();
}
}
///////////////////////////////////////////////////
// parsing functions
internal string GetTextMessage(string Buffer, int MessageIndex)
{
int end, begin;
begin = end = 0;
try
{
if(m_strContType.IndexOf("digest") >= 0)
{
// this is a digest method
ParseDigestMessage(Buffer, MessageIndex);
}
else
{
// find "\r\n\r\n" denoting end of header
if((begin = Buffer.IndexOf("\r\n\r\n")) < 0)
throw new POP3ParseException("GetMessageText could not find end of header");
// find end of text
// if((end = Buffer.LastIndexOfAny(NON_WHITE.ToCharArray())) < 0)
if((end = Buffer.LastIndexOfAny(ALPHABET.ToCharArray())) < 0)
throw new POP3ParseException("GetMessageText could not find end of message text"); begin += 4;
m_strMsgText = Buffer.Substring(begin, end - begin + 1);
}
}
catch(Exception e)
{
m_pSAPOP3.TRACE(e.ToString());
if(m_pSAPOP3.Log)
{
string strErr = "SAPOP3Message::GetTextMessage()";
strErr += e.Message;
m_pSAPOP3.LogError(strErr);
}
}
return null;
}
internal bool ParseMixedMessage(string Buffer, int MessageIndex)
{
m_nMIMECount = 0;
try
{
int end, begin, pos;
end = begin = pos = 0;
while((begin = Buffer.IndexOf(m_strBoundary, pos)) >= 0)
{
pos = begin + 1;
if((end = Buffer.IndexOf(m_strBoundary, pos)) < 0)
{
// make we're at the end of the buffer
if(Buffer.Substring((begin + m_strBoundary.Length), 2) == "--")
{
return true;
}
else
throw new POP3ParseException("Could not find boundary");
}
// we want to find the same boundary at the next loop
pos++; // remove boundary from buffer
begin += m_strBoundary.Length; m_mimeEntity.Add(new SAMimeEntity(m_pSAPOP3, Buffer.Substring(begin, end - begin)));
ProcessMIMEEntity((SAMimeEntity)m_mimeEntity[m_nMIMECount]); // set index
((SAMimeEntity)m_mimeEntity[m_nMIMECount]).m_nIndex = m_nMIMECount;
m_nMIMECount++;
}
return true;
}
catch(Exception e)
{
m_pSAPOP3.TRACE(e.ToString());
if(m_pSAPOP3.Log)
{
string strErr = "SAPOP3Message::ParseMixedMessage()";
strErr += e.Message;
m_pSAPOP3.LogError(strErr);
}
return false;
}
}