我想通过SMTP将C#中的电子邮件发送到不同的邮件提供商示例Gmail,Yahoo,AOL,Msn,Live等,这样如果我的计算机通过代理连接到互联网或直接连接到互联网,我的代码就可以正常工作即可。 (代理是一个转发代理,从内部网络接收请求并将它们转发到Internet,我在I.E.中配置代理) .................................
如果没有通过代理连接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);
}
这工作得非常好,但我希望在通过代理连接时发送电子邮件。
我读了很多帖子,比如
Sending Mail over proxy server
ASP.net SMTP Mail though Proxy
Is there .NET library for email sending via PROXY?
他们都声明这是不可能的,但在搜索时,我发现了chilkat库limilabs sample ,它允许用户通过代理配置代理来发送邮件。
我已经研究了很多,我已经阅读了SOCKS代理,了解了如何使用原始套接字发送SMTP邮件,但我无法找到解决方案丢失的问题。
如果有任何人遇到同样的问题或任何想法我能做什么,我会很感激以前做过的一些工作的想法吗?
编辑: - 正如我已经提到的那样,我使用 Chilkat和limilabs 找到了样本,这意味着我不想使用那些我不允许使用任何第三方dll
答案 0 :(得分:3)
通过代理服务器发送邮件有点棘手,但最后通过使用代码通过套接字发送邮件解决了问题。
在发布答案后期,但我们假设它可能对其他人有帮助。
从link
的代码处获得帮助附加下面的代码,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 .....