没有凭据的SMTP邮件

时间:2017-06-15 06:56:21

标签: c# email

注意:下面的代码原本不是我的想法。这只是Peter Bromberg代码article中的修改。

这段代码对我有用,但发送电子邮件有点慢(甚至只发一封),我不知道为什么。另外,我正在尝试发送HTML Body,但它总是发送TEXT Body。请帮忙。



提前谢谢你!

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;
    }
}
}

要测试上面的代码我使用这个

  SMTP.SmtpDirect.SmtpServer = "myhost.loc";
  MailMessage msg = new MailMessage();
  msg.Body = "TEST";
  msg.From = new MailAddress("from@mail.com");
  msg.To.Add("to@mail.com");
  msg.Subject = "TEST SUBJECT";

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

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

2 个答案:

答案 0 :(得分:1)

您可以同时发送多个电子邮件。但要小心并发邮件发送操作的数量。通过多次测试调整并发邮件发送操作的数量。这种方法可以帮到你

答案 1 :(得分:0)

从邮件发送html正文。使用

msg.BodyFormat = MailFormat.Html; 

如果您在当前类中使用System.Web.Mail命名空间。(请不要使用此命名空间,因为MailFormat在更高.net框架中已过时

否则使用

msg.IsBodyHtml = true;

如果您使用的是System.Net.Mail命名空间。

如果无效,请尝试添加此代码段。:

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