3

我想通过 SMTP 将 C# 中的电子邮件发送到不同的邮件提供商,例如 Gmail、Yahoo、AOL、Msn、Live 等,这样如果我的计算机通过代理连接到互联网或直接连接到互联网,我的代码就可以正常工作。(代理是一个转发代理,从内部网络接收请求并将它们转发到 Internet,我在 IE 中将代理配置为)
...................... …………

如果 PC 未通过代理连接,我有代码可以发送 SMTP 邮件

    public void SendMail(string senderId, string password, List<string> To, List<string> CC, List<string> BCC, string Subject, string Body, List<Attachment> Attachment)
    {
        SmtpClient SmtpServer = null;
        string[] ss = senderId.Split('@');

        string ServerName = ss[1].Substring(0, ss[1].IndexOf("."));

        switch (ServerName.ToLower())
        {
            case "gmail":
                SmtpServer = new SmtpClient("smtp.gmail.com");
                SmtpServer.Port = 587;
                SmtpServer.Credentials = new System.Net.NetworkCredential(senderId, password);
                SmtpServer.EnableSsl = true;
                break;
            case "msn":
            case "live":
            case "hotmail":
            case "outlook":
                SmtpServer = new SmtpClient("smtp.live.com");
                SmtpServer.Port = 25;
                SmtpServer.Credentials = new System.Net.NetworkCredential(senderId, password);
                SmtpServer.EnableSsl = true;
                break;

            case "aol":
                SmtpServer = new SmtpClient("smtp.aol.com");
                SmtpServer.Port = 25;
                SmtpServer.Credentials = new System.Net.NetworkCredential(senderId, password);
                SmtpServer.EnableSsl = true;
                break;
            case "yahoo":
            case "ymail":
            case "rocketmail":
            case "yahoomail":
                SmtpServer = new SmtpClient("smtp.mail.yahoo.com");
                SmtpServer.Port = 25;
                SmtpServer.Credentials = new System.Net.NetworkCredential(senderId, password);
                SmtpServer.EnableSsl = false;
                break;
            default:

                break;


        }
        SmtpServer.DeliveryMethod = SmtpDeliveryMethod.Network;

        MailMessage mail = new MailMessage();
        mail.From = new MailAddress(senderId);

        foreach (string item in To)
        {
            mail.To.Add(item);
        }
        foreach (string item in CC)
        {
            mail.CC.Add(item);
        }
        foreach (string item in BCC)
        {
            mail.Bcc.Add(item);
        }

        mail.Subject = Subject;
        mail.Body = Body;

        foreach (Attachment item in Attachment)
        {
            mail.Attachments.Add(item);
        }

        SmtpServer.Send(mail);

    }

这工作得很好,但我想在通过代理连接时发送电子邮件。

我已经阅读了很多帖子,例如 通过代理服务器
ASP.net SMTP 邮件通过代理发送邮件
是否有 .NET 库用于通过代理发送电子邮件?
他们都说这是不可能的,但是在搜索时我发现了 chilkat 库,limlabs 示例,它允许用户通过配置代理来通过代理发送邮件。
我研究了很多,我读过 SOCKS 代理,学习了如何使用原始套接字发送 SMTP 邮件,但我无法找到缺少的解决方案。
如果有人遇到同样的问题或任何想法我能做些什么,我将不胜感激以前做过的一些工作的任何想法?

编辑:-正如我已经提到的那样,我找到了使用Chilkat 和 limilabs的样本,这意味着我不想使用这些样本,并且我不允许使用任何第三方 dll

4

1 回答 1

3

通过代理服务器发送邮件有点棘手,但最终通过使用代码通过套接字发送邮件解决了这个问题。

发布答案较晚,但假设它可能对其他人有帮助。

从链接的代码中获得帮助

附上下面的代码,SmtpServer对象与所描述的相同,

   #region ..... SOCKET MAIL .....

    private enum SMTPResponse : int
    {
        /// <summary>
        /// 220
        /// </summary>
        CONNECT_SUCCESS = 220,
        /// <summary>
        /// 235
        /// </summary>
        CRED_SUCCESS = 235,
        /// <summary>
        /// 250
        /// </summary>
        GENERIC_SUCCESS = 250,
        /// <summary>
        /// 334
        /// </summary>
        AUTH_SUCCESS = 334,
        /// <summary>
        /// 354
        /// </summary>
        DATA_SUCCESS = 354,
        /// <summary>
        /// 221
        /// </summary>
        QUIT_SUCCESS = 221
    }

    public static string EncodeTo64(string toEncode)
    {

        byte[] toEncodeAsBytes = System.Text.Encoding.ASCII.GetBytes(toEncode);

        string returnValue = System.Convert.ToBase64String(toEncodeAsBytes, Base64FormattingOptions.None);

        return returnValue;

    }

    public bool SendFromSocket(MailMessage message)
    {
        var requestUri = new System.Uri("smtps://" +SmtpServer.Host +":"+SmtpServer.Port);

        Uri proxy = null;
        //This is magic code which does your job for the proxy 
        using (var web = new System.Net.WebClient())
        {                
            proxy = web.Proxy.GetProxy(requestUri);                
        }

        using (var s = new TcpClient(proxy.DnsSafeHost, proxy.Port  ))
        {               
            using (var stream = s.GetStream())
            using (var clearTextReader = new StreamReader(stream))
            using (var clearTextWriter = new StreamWriter(stream) { AutoFlush = true })
            using (var sslStream = new SslStream(stream))
            {
                if (!Check_Response(clearTextReader, SMTPResponse.CONNECT_SUCCESS))
                {
                    s.Close();
                    return false;
                }

                clearTextWriter.WriteLine("HELO");
                if (!Check_Response(clearTextReader, SMTPResponse.GENERIC_SUCCESS))
                {
                    s.Close();
                    return false;
                }

                clearTextWriter.WriteLine("STARTTLS");
                if (!Check_Response(clearTextReader, SMTPResponse.CONNECT_SUCCESS))
                {
                    s.Close();
                    return false;
                }


                sslStream.AuthenticateAsClient(SmtpServer.Host);
                bool flag = sslStream.IsAuthenticated;

                using (var reader = new StreamReader(sslStream))
                using (var writer = new StreamWriter(sslStream) { AutoFlush = true })
                {                       
                    writer.WriteLine(string.Format("EHLO {0}", SmtpServer.Host));
                    if (!Check_Response(reader, SMTPResponse.GENERIC_SUCCESS))
                    {
                        s.Close();
                        return false;
                    }

                    writer.WriteLine("AUTH LOGIN");
                    if (!Check_Response(reader, SMTPResponse.AUTH_SUCCESS))
                    {
                        s.Close();
                        return false;
                    }

                    writer.WriteLine(EncodeTo64(SenderId));
                    if (!Check_Response(reader, SMTPResponse.AUTH_SUCCESS))
                    {
                        s.Close();
                        return false;
                    }

                    writer.WriteLine(EncodeTo64(Password));
                    if (!Check_Response(reader, SMTPResponse.CRED_SUCCESS))
                    {
                        s.Close();
                        return false;
                    }

                    writer.WriteLine("MAIL FROM: <{0}>", message.From);
                    if (!Check_Response(reader, SMTPResponse.GENERIC_SUCCESS))
                    {

                        s.Close();
                        return false;
                    }

                    foreach (MailAddress To in message.To)
                    {
                        writer.WriteLine("RCPT TO: <{0}>", To.Address);
                        if (!Check_Response(reader, SMTPResponse.GENERIC_SUCCESS))
                        {
                            s.Close();
                            return false;
                        }
                    }

                    if (message.CC != null)
                    {
                        foreach (MailAddress cc in message.CC)
                        {
                            writer.WriteLine(string.Format("RCPT TO: <{0}>", cc.Address));
                            if (!Check_Response(reader, SMTPResponse.GENERIC_SUCCESS))
                            {
                                s.Close();
                                return false;
                            }
                        }
                    }

                    StringBuilder Header = new StringBuilder();
                    Header.Append("From: " + message.From + "\r\n");
                    Header.Append("To: ");
                    for (int i = 0; i < message.To.Count; i++)
                    {
                        Header.Append(i > 0 ? "," : "");
                        Header.Append(message.To[i].Address);
                    }
                    Header.Append("\r\n");
                    if (message.CC != null)
                    {
                        Header.Append("Cc: ");
                        for (int i = 0; i < message.CC.Count; i++)
                        {
                            Header.Append(i > 0 ? "," : "");
                            Header.Append(message.CC[i].Address);
                        }
                        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.);
                                sb.Append("--unique-boundary-1\r\n");
                                sb.Append("Content-Type: application/octet-stream; file=" + a.Name + "\r\n");
                                sb.Append("Content-Transfer-Encoding: base64\r\n");
                                sb.Append("Content-Disposition: attachment; filename=" + a.Name + "\r\n");
                                sb.Append("\r\n");
                                Stream fs = a.ContentStream;
                                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();
                    }

                    writer.WriteLine("DATA\r\n");
                    if (!Check_Response(reader, 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");
                    writer.WriteLine(Header.ToString());
                    if (!Check_Response(reader, SMTPResponse.GENERIC_SUCCESS))
                    {
                        s.Close();
                        return false;
                    }

                    writer.WriteLine("QUIT\r\n");
                    Check_Response(reader, SMTPResponse.QUIT_SUCCESS);
                    s.Close();
                    return true;
                }
            }

        }
    }

    private static bool Check_Response(StreamReader netStream, SMTPResponse response_expected)
    {

        int response;

        int read = 0;

        StringBuilder sResponse = new StringBuilder();
        do
        {
            char[] buffer = new char[1024];                
            read = netStream.Read(buffer, 0, buffer.Length);
            sResponse.Append(buffer);                
        }
        while (read == 1024);

        response = Convert.ToInt32(sResponse.ToString().Substring(0, 3));

        if (response != (int)response_expected)
            return false;
        return true;
    }

    #endregion ..... SOCKET MAIL .....
于 2017-03-10T13:42:16.750 回答