/*
* Copyright 2003-2004, Axosoft, LLC
* You are free to distribute this code royalty-free as you wish, however, we only ask
* that you leave this copyright notice at the top of the source file giving Axosoft
* credit for this source code. If you find any bugs or want to contribute your
* enhancements, please send them to support@axosoft.com.
*
* Visit Axosoft at http://www.axosoft.com
*/
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace WindowsApplication1
{
public class SmtpException : ApplicationException
{
public SmtpException(string message) : base(message)
{
}
}
///
/// Indicates the type of message to be sent
///
public enum MessageType
{
///
/// The message is plain text
///
Text = 0,
///
/// The message is HTML
///
HTML = 1
}
///
/// A mail message that can be sent using the Smtp class
///
public class MailMessages
{
private string _emailFrom = "";
public string EmailFrom
{
get { return _emailFrom; }
set { _emailFrom = value; }
}
private string _emailSubject = "";
public string EmailSubject
{
get { return _emailSubject; }
set { _emailSubject = value; }
}
private ArrayList _emailTo = null;
public ArrayList EmailTo
{
get { return _emailTo; }
}
public void AddEmailTo(string email)
{
if(_emailTo == null)
_emailTo = new ArrayList();
_emailTo.Add(email);
}
private string _emailMessage = "";
public string EmailMessage
{
get { return _emailMessage; }
set { _emailMessage = value; }
}
private MessageType _emailMessageType = MessageType.Text;
public MessageType EmailMessageType
{
get { return _emailMessageType; }
set { _emailMessageType = value; }
}
}
///
/// This class allows sending of e-mails through Smtp
/// For help on SMTP, look up http://www.faqs.org/rfcs/rfc821.html
///
public class Smtp
{
#region Class properties
private string _serverSmtp = "";
public string SmtpServer
{
get { return _serverSmtp; }
set { _serverSmtp = value; }
}
private int _portSmtp = 25;
public int SmtpPort
{
get { return _portSmtp; }
set { _portSmtp = value; }
}
private string _userSmtp = "";
public string SmtpUser
{
get { return _userSmtp; }
set { _userSmtp = value; }
}
private string _passwordSmtp = "";
public string SmtpPassword
{
get { return _passwordSmtp; }
set { _passwordSmtp = value; }
}
#endregion
public Smtp()
{
}
#region Public methods
///
/// Sends the e-mail based on the properties set for this object
///
public void SendEmail(MailMessages msg)
{
int code;
if(_serverSmtp == "" || msg.EmailFrom == "" || msg.EmailSubject == "" || msg.EmailTo == null)
{
throw new SmtpException("Invalid Smtp or email parameters.");
}
// open a connection to the Smtp server
using(TcpClient smtpSocket = new TcpClient(_serverSmtp, _portSmtp))
using(NetworkStream ns = smtpSocket.GetStream())
{
// get response from Smtp server
code = GetSmtpResponse(ReadBuffer(ns));
if(code != 220)
{
throw new SmtpException("Error connecting to Smtp server. (" + code.ToString() + ")");
}
// EHLO
WriteBuffer(ns, "ehlo\r\n");
// get response from Smtp server
string buffer = ReadBuffer(ns);
code = GetSmtpResponse(buffer);
if(code != 250)
{
throw new SmtpException("Error initiating communication with Smtp server. (" + code.ToString() + ")");
}
// check for AUTH LOGIN
if(buffer.IndexOf("AUTH LOGIN") >= 0)
{
// AUTH LOGIN
WriteBuffer(ns, "auth login\r\n");
// get response from Smtp server
code = GetSmtpResponse(ReadBuffer(ns));
if(code != 334)
{
//throw new SmtpException("Error initiating Auth=Login. (" + code.ToString() + ")");
}
// username:
WriteBuffer(ns, System.Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(_userSmtp)) + "\r\n");
// get response from Smtp server
code = GetSmtpResponse(ReadBuffer(ns));
if(code != 334)
{
//throw new SmtpException("Error setting Auth user name. (" + code.ToString() + ")");
}
// password:
WriteBuffer(ns, System.Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(_passwordSmtp)) + "\r\n");
// get response from Smtp server
code = GetSmtpResponse(ReadBuffer(ns));
if(code != 235)
{
//throw new SmtpException("Error setting Auth password. (" + code.ToString() + ")");
}
}
// MAIL FROM:
WriteBuffer(ns, "mail from: <" + msg.EmailFrom + ">\r\n");
// get response from Smtp server
code = GetSmtpResponse(ReadBuffer(ns));
if(code != 250)
{
throw new SmtpException("Error setting sender email address. (" + code.ToString() + ")");
}
// RCPT TO:
foreach(string sEmailTo in msg.EmailTo)
{
WriteBuffer(ns, "rcpt to:<" + sEmailTo + ">\r\n");
// get response from Smtp server
code = GetSmtpResponse(ReadBuffer(ns));
if(code != 250 && code != 251)
{
throw new SmtpException("Error setting receipient email address. (" + code.ToString() + ")");
}
}
// DATA
WriteBuffer(ns, "data\r\n");
// get response from Smtp server
code = GetSmtpResponse(ReadBuffer(ns));
if(code != 354)
{
throw new SmtpException("Error starting email body. (" + code.ToString() + ")");
}
// Repeat the from and to addresses in the data section
WriteBuffer(ns, "from:<" + msg.EmailFrom + ">\r\n");
foreach(string sEmailTo in msg.EmailTo)
{
WriteBuffer(ns, "to:<" + sEmailTo + ">\r\n");
}
WriteBuffer(ns, "Subject:" + msg.EmailSubject + "\r\n");
switch(msg.EmailMessageType)
{
case MessageType.Text:
// send text message
WriteBuffer(ns, "\r\n" + msg.EmailMessage + "\r\n.\r\n");
break;
case MessageType.HTML:
// send HTML message
//WriteBuffer(ns, "MIME-Version: 1.0\r\n");
//WriteBuffer(ns, "Content-type: text/html;charset=GB2312\r\n");
//WriteBuffer(ns, "Content-type: text/plain; charset=gb18030\r\n");
//Content-Type: text/plain; charset=ISO-8859-1
//Content-transfer-encoding: base64
//WriteBuffer(ns, "Content-transfer-encoding: base64\r\n");
WriteBuffer(ns, "\r\n" + msg.EmailMessage + "\r\n.\r\n");
break;
}
// get response from Smtp server
code = GetSmtpResponse(ReadBuffer(ns));
if(code != 250)
{
throw new SmtpException("Error setting email body. (" + code.ToString() + ")");
}
// QUIT
WriteBuffer(ns, "quit\r\n");
}
}
#endregion
#region Private methods
///
/// Looks for an Smtp response code inside a repsonse string
///
/// The response string to be searched
/// The int value of the Smtp reponse code
private int GetSmtpResponse(string sResponse)
{
int response = 0;
int iSpace = sResponse.IndexOf(" ");
int iDash = sResponse.IndexOf("-");
if(iDash > 0 && iDash < iSpace)
iSpace = sResponse.IndexOf("-");
try
{
if(iSpace > 0)
response = int.Parse(sResponse.Substring(0, iSpace));
}
catch(Exception)
{
// error - ignore it
}
return response;
}
///
/// Write a string to the network stream
///
/// The network stream on which to write
/// The string to write to the stream
private void WriteBuffer(NetworkStream ns, string sBuffer)
{
try
{
byte[] buffer = Encoding.ASCII.GetBytes(sBuffer);
ns.Write(buffer, 0, buffer.Length);
}
catch(System.IO.IOException)
{
// error writing to stream
throw new SmtpException("Error sending data to Smtp server.");
}
}
///
/// Reads a response from the network stream
///
/// The network stream from which to read
/// A string representing the reponse read
private string ReadBuffer(NetworkStream ns)
{
byte[] buffer = new byte[1024];
int i=0;
int b;
int timeout = System.Environment.TickCount;
try
{
// wait for data to show up on the stream
while(!ns.DataAvailable && ((System.Environment.TickCount - timeout) < 20000))
{
System.Threading.Thread.Sleep(100);
}
if(!ns.DataAvailable)
throw new SmtpException("No response received from Smtp server.");
// read while there's data on the stream
while(i < buffer.Length && ns.DataAvailable)
{
b = ns.ReadByte();
buffer[i++] = (byte)b;
}
}
catch(System.IO.IOException)
{
// error reading from stream
throw new SmtpException("Error receiving data from Smtp server.");
}
return Encoding.ASCII.GetString(buffer);
}
#endregion
}
}