Kerber
Kerber

Reputation: 61

SMTP Mail without Credentials

Note: The code below is not originally my idea. It is just a modification of the code of Peter Bromberg in his article.

This code works on me but a little bit slow in sending emails(even only one is sent) and I'm not sure why. Also, I am trying to send HTML Body but it always sends TEXT Body. Please help.



Thank you in advance!

using System.Text;
using System.IO;
using System.Net.Sockets;
using System.Net;
using System.Net.Mail;

namespace SMTP
{

/// <summary>
/// provides methods to send email via smtp direct to mail server
/// </summary>
public static class SmtpDirect
{
    public static System.Threading.ManualResetEvent GetHostEntryFinished =
     new System.Threading.ManualResetEvent(false);

    public class ResolveState
    {
        string hostName;
        System.Net.IPHostEntry resolvedIPs;

        public ResolveState(string host)
        {
            hostName = host;
        }

        public IPHostEntry IPs
        {
            get { return resolvedIPs; }
            set { resolvedIPs = value; }
        }
        public string host
        {
            get { return hostName; }
            set { hostName = value; }
        }
    }

    /// <summary>
    /// Get / Set the name of the SMTP mail server
    /// </summary>
    public static string SmtpServer { get; set; }

    // Record the IPs in the state object for later use.
    public static void GetHostEntryCallback(IAsyncResult ar)
    {
        ResolveState ioContext = (ResolveState)ar.AsyncState;

        ioContext.IPs = Dns.EndGetHostEntry(ar);
        GetHostEntryFinished.Set();
    }

    private enum SMTPResponse : int
    {
        CONNECT_SUCCESS = 220,
        GENERIC_SUCCESS = 250,
        DATA_SUCCESS = 354,
        QUIT_SUCCESS = 221
    }

    /// <summary>
    /// Send Email
    /// </summary>
    /// <param name="message"></param>
    /// <returns></returns>
    public static bool Send(MailMessage message)
    {
        try
        {
            GetHostEntryFinished.Reset();
            ResolveState ioContext = new ResolveState(SmtpServer);

            Dns.BeginGetHostEntry(ioContext.host,
                new AsyncCallback(GetHostEntryCallback), ioContext);

            // Wait here until the resolve completes (the callback 
            // calls .Set())
            GetHostEntryFinished.WaitOne();

            IPEndPoint endPt = new IPEndPoint(ioContext.IPs.AddressList[0], 25);
            Socket s = new Socket(endPt.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
            bool conn = false;
            foreach (IPAddress ip in ioContext.IPs.AddressList)
            {
                endPt = new IPEndPoint(ioContext.IPs.AddressList[0], 25);
                s = new Socket(endPt.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                s.Connect(endPt);
                if (Check_Response(s, SMTPResponse.CONNECT_SUCCESS))
                {
                    conn = true;
                }
            }

            if (!conn)
            {
                s.Close();
                return false;
            }

            Senddata(s, string.Format("HELO {0}\r\n", Dns.GetHostName()));
            if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))
            {
                s.Close();
                return false;
            }

            Senddata(s, string.Format("MAIL From: {0}\r\n", message.From));
            if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))
            {
                s.Close();
                return false;
            }

            string _To = message.To[0].ToString();
            string[] Tos = _To.Split(new char[] { ';' });
            foreach (string To in Tos)
            {
                Senddata(s, string.Format("RCPT TO: {0}\r\n", To));
                if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))
                {
                    s.Close();
                    return false;
                }
            }

            if (message.CC != null)
            {
                Tos = message.CC.ToString().Split(new char[] { ';' });
                foreach (string To in Tos)
                {
                    Console.WriteLine("RCPT To");
                    Senddata(s, string.Format("RCPT TO: {0}\r\n", To));
                    if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))
                    {
                        s.Close();
                        return false;
                    }
                }
            }

            StringBuilder Header = new StringBuilder();
            Header.Append("From: " + message.From + "\r\n");
            Tos = message.To.ToString().Split(new char[] { ';' });
            Header.Append("To: ");
            for (int i = 0; i < Tos.Length; i++)
            {
                Header.Append(i > 0 ? "," : "");
                Header.Append(Tos[i]);
            }
            Header.Append("\r\n");
            if (message.CC != null)
            {
                Tos = message.CC.ToString().Split(new char[] { ';' });
                Header.Append("Cc: ");
                for (int i = 0; i < Tos.Length; i++)
                {
                    Header.Append(i > 0 ? "," : "");
                    Header.Append(Tos[i]);
                }
                Header.Append("\r\n");
            }
            Header.Append("Date: ");
            Header.Append(DateTime.Now.ToString("ddd, d M y H:m:s z"));
            Header.Append("\r\n");
            Header.Append("Subject: " + message.Subject + "\r\n");
            Header.Append("X-Mailer: SMTPDirect v1\r\n");
            string MsgBody = message.Body;
            if (!MsgBody.EndsWith("\r\n"))
                MsgBody += "\r\n";
            if (message.Attachments.Count > 0)
            {
                Header.Append("MIME-Version: 1.0\r\n");
                Header.Append("Content-Type: multipart/mixed; boundary=unique-boundary-1\r\n");
                Header.Append("\r\n");
                Header.Append("This is a multi-part message in MIME format.\r\n");
                StringBuilder sb = new StringBuilder();
                sb.Append("--unique-boundary-1\r\n");
                sb.Append("Content-Type: text/plain\r\n");
                sb.Append("Content-Transfer-Encoding: 7Bit\r\n");
                sb.Append("\r\n");
                sb.Append(MsgBody + "\r\n");
                sb.Append("\r\n");

                foreach (object o in message.Attachments)
                {
                    Attachment a = o as Attachment;
                    byte[] binaryData;
                    if (a != null)
                    {
                        FileInfo f = new FileInfo(a.Name);
                        sb.Append("--unique-boundary-1\r\n");
                        sb.Append("Content-Type: application/octet-stream; file=" + f.Name + "\r\n");
                        sb.Append("Content-Transfer-Encoding: base64\r\n");
                        sb.Append("Content-Disposition: attachment; filename=" + f.Name + "\r\n");
                        sb.Append("\r\n");
                        FileStream fs = f.OpenRead();
                        binaryData = new Byte[fs.Length];
                        long bytesRead = fs.Read(binaryData, 0, (int)fs.Length);
                        fs.Close();
                        string base64String = System.Convert.ToBase64String(binaryData, 0, binaryData.Length);

                        for (int i = 0; i < base64String.Length;)
                        {
                            int nextchunk = 100;
                            if (base64String.Length - (i + nextchunk) < 0)
                                nextchunk = base64String.Length - i;
                            sb.Append(base64String.Substring(i, nextchunk));
                            sb.Append("\r\n");
                            i += nextchunk;
                        }
                        sb.Append("\r\n");
                    }
                }
                MsgBody = sb.ToString();
            }

            Senddata(s, ("DATA\r\n"));
            if (!Check_Response(s, SMTPResponse.DATA_SUCCESS))
            {
                s.Close();
                return false;
            }
            Header.Append("\r\n");
            Header.Append(MsgBody);
            Header.Append(".\r\n");
            Header.Append("\r\n");
            Header.Append("\r\n");

            Senddata(s, Header.ToString());
            if (!Check_Response(s, SMTPResponse.GENERIC_SUCCESS))
            {
                s.Close();
                return false;
            }

            Senddata(s, "QUIT\r\n");
            Check_Response(s, SMTPResponse.QUIT_SUCCESS);
            s.Close();
            return true;
        }
        catch (Exception ex)
        {
            return false;
        }

    }

    private static void Senddata(Socket s, string msg)
    {
        try
        {
            byte[] _msg = Encoding.ASCII.GetBytes(msg);
            s.Send(_msg, 0, _msg.Length, SocketFlags.None);
        }
        catch (Exception ex)
        {
            Console.WriteLine("SendData Error: " + ex.Message);
        }
    }
    private static bool Check_Response(Socket s, SMTPResponse response_expected)
    {
        string sResponse;
        int response;
        byte[] bytes = new byte[1024];
        while (s.Available == 0)
        {
            System.Threading.Thread.Sleep(100);
        }

        s.Receive(bytes, 0, s.Available, SocketFlags.None);
        sResponse = Encoding.ASCII.GetString(bytes);
        response = Convert.ToInt32(sResponse.Substring(0, 3));
        if (response != (int)response_expected)
            return false;
        return true;
    }
}
}

To test the code above I use this

  SMTP.SmtpDirect.SmtpServer = "myhost.loc";
  MailMessage msg = new MailMessage();
  msg.Body = "TEST";
  msg.From = new MailAddress("[email protected]");
  msg.To.Add("[email protected]");
  msg.Subject = "TEST SUBJECT";

  //msg.Headers.Add("Reply-to", "");

  if (SMTP.SmtpDirect.Send(msg))
  {
     Console.WriteLine("Sent OK");
  }
  else
  {
     Console.WriteLine("Something BAD Happened!");
  }

Upvotes: 0

Views: 187

Answers (2)

Rajput
Rajput

Reputation: 2607

For sending html body from mail. use

msg.BodyFormat = MailFormat.Html; 

if you are using System.Web.Mail namespace in current class.(Please do not use this namespace since MailFormat is obsolete in higher .net framework)

Otherwise use

msg.IsBodyHtml = true;

if you are using System.Net.Mail namespace.

If nothing works then try to add this code snippet.:

AlternateView htmlView = 
     AlternateView.CreateAlternateViewFromString(yourbody, Encoding.UTF8, "text/html");
msg.AlternateViews.Add(htmlView);
msg.Body = yourbody;
msg.IsBodyHtml = true;

Upvotes: 0

cahit beyaz
cahit beyaz

Reputation: 5117

You can send multiple emmails at the same time. But be careful with the number of concurrent mail send operations. Adjust the number of concurrent mail send operations by several tests. This aproach may help you

Upvotes: 1

Related Questions