自己动手,一步一步实现邮件群发.NET源码(3)
--群发单点接收
作者:长江支流
关键字:.NET、邮件、群发
在前面发布了邮件群发器后,自己使用的过程中,碰到了如下问题。
- 大量邮件可能存在Excel或文档中,要直接拷贝使用
- 群发过程中, 发件人抄送的邮件,会显示在每个收件人中,这不利于安全
- 群发过程中,由于抄送密送大量邮件,捕获错误后,不知道哪些邮件正确发出哪些有异常
由于发送邮件,可能从文档摘记中来,例如有如下背景,很多网友来电要金质打印通源码,我就记录下来,回复邮件时有的发送失败,我把这些信息临时放记事本中,没有统一存在数据库。我现在想发邮件,如果一个邮件一个邮件的敲键盘,那肯定太原始,一个邮件一个邮件拷贝,虽然聪明点少敲下键盘,但是如果我直接把文件内容复制或打开就能把邮件区分开来发送,那不是一步到位吗?
例如如下记录文档txt:
2006年3月7日,登记
XX@yeah.net
YY@msn.com
...
2006年3月4日,发送邮件失败
aa@hotmail.com
bb@163.com
...
--
敬请关注我的BLOG和网站上最新消息!
MIS金质打印通 通打天下报表
http://www.webmis.com.cn
http://blog.csdn.net/flygoldfish
QQ:150439795
长江支流
我Ctrl+C,然后,复制到我的收件人中,结果发送时因为有些不是邮件地址会出错。于是我在收件人中增加了一个双击事件,弹出一个窗口,该窗口有一个大的文本框,用来接收显示文本,并有一个格式化按钮用来去掉回车换行等,将邮件用英文半角逗号分隔。
为了收信人不看到抄送人的邮箱,于是用循环单个发送,在发送时,如果分隔出来的邮件没有@标志那明显不是邮件,跳过发送。
在捕获发送错误时,有时因为发送邮件数量过大,而收到服务器一个返回信息,例如网易的返回是:
正在处理错误。 服务器响应为: MI:SFQ 0,smtp3,DdGowEC5mldx_CBQsc4QFA--.106S3 1344339057http://mail.163.com/help/help_spam_16.htm?ip=111.161.77.192&hostid=smtp3&time=1344339057
打开网页邮箱服务说明,发现了MI:SFQ正是错误代码,再摘录几个:
* 如下经常出会出现,邮件数量超出限制
•450 MI:DMC 当前连接发送的邮件数量超出限制。请减少每次连接中投递的邮件数量;
•451 MI:SFQ 发信人在15分钟内的发信数量超过限制,请控制发信频率;
•450 RP:DRC 当前连接发送的收件人数量超出限制。请控制每次连接投递的邮件数量;
•451 RP:QRC 发信方短期内累计的收件人数量超过限制,该发件人被临时禁止发信。请降低该用户发信频率;
•550 MI:STC 发件人当天的连接数量超出了限定数量,当天不再接受该发件人的邮件。请控制连接次数;
•550 RP:FRL 网易邮箱不开放匿名转发(Open relay);
•550 RP:RCL 群发收件人数量超过了限额,请减少每封邮件的收件人数量;
如果我一个一个的判断,今天是网易,明天是新浪,永远也加不完。最灵活的办法是根据群发人使用的邮箱,自己去设置返回码与处理对策及友好提示,把它们存在配置文件中。
我只做一个简单处理,把由于发送数量太多及暂时限制连接存在配置文件中,当捕获错误时如果是指定的代码,我就暂时停顿一会后再发,当然可以重发。
//发送邮件
private bool SendMail()
{
#region 实现...
//网络设置
SmtpClient smtp = new SmtpClient();
//将smtp的出站方式设为 Network
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.Port = m_Setting.SmtpPort;
smtp.Host = m_Setting.SmtpServer;
smtp.EnableSsl = m_Setting.SmtpSSL;
//邮件认证,即邮箱用户名称密码
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential(m_Setting.SenderMail, m_Setting.SenderPassword);
//邮件信息
MailMessage mm = new MailMessage();
mm.Priority = MailPriority.Normal;
//发件人
mm.From = new MailAddress(m_Setting.SenderMail, m_Setting.SenderDisplay);
//接收回复邮件
if (m_Setting.ReplyToMail != null && m_Setting.ReplyToMail != "")
{
//mm.ReplyTo = new MailAddress("MisGoldPrinter@163.com", "(答复)金质打印通");
mm.ReplyTo = new MailAddress(m_Setting.ReplyToMail, m_Setting.ReplyToDisplay);
}
//主题
mm.Subject = txtSubject.Text;
//内容
//mm.SubjectEncoding = Encoding.Unicode;
//mm.BodyEncoding = Encoding.Unicode;
//mm.IsBodyHtml = false;
mm.IsBodyHtml = chkHtml.Checked;
mm.Body = txtBody.Text;
//mm.IsBodyHtml = true;
//mm.Body = "<font size = \"21\" color=\"blue\">长江支流金质打印通,准备升级</font>";
,请http://goldprinter.taobao.com/查看注册
//附件
for (int i = 0; i < this.lstFiles.Items.Count; i++)
{
mm.Attachments.Add(new Attachment(this.lstFiles.Items[i].ToString()));
}
//接收人、抄送、密送
//多个邮件英文逗号分开
//mm.CC.Add("FlyGoldFish@163.com,MISGoldPrinter@163.com");
//mm.CC.Add(new MailAddress("FlyGoldFish@163.com", "金质打印通,来自网易测试"));
if (chkSplit.Checked)
{
//单个分离发信,收件人只看到自己,看不到其它群发的收件人
#region 实现...
//格式错误、发送失败以及成功的邮件
List<string> arrErrorMails = new List<string>();
List<string> arrFaileErrorMails = new List<string>();
List<string> arrSuccessMails = new List<string>();
int iTotalCount = 0;
int iSuccessCount = 0;
string strMails = ReplaceMailList(txtTO.Text) + "," + ReplaceMailList(txtCC.Text) + "," + ReplaceMailList(txtBCC.Text);
string[] arrMails = strMails.Split(',');
this.pnStatus.Visible = true;
this.pbSend.Minimum = 1;
this.pbSend.Maximum = arrMails.Length;
for (int i = 0; i < arrMails.Length; i++)
{
this.pbSend.Value = i+1;
this.lblStatus.Text = string.Format("共{0}封邮件,正在发第{1}封,已发送成功{2}", arrMails.Length.ToString(), (i + 1), i.ToString(), iTotalCount.ToString());
this.lblStatus.Refresh();
this.pnStatus.Refresh();
//跳过只有分隔但没指定邮件的空串
if (arrMails[i].Trim() == "" || arrMails[i].IndexOf('@') < 1)
{
continue;
}
//有效数量
iTotalCount++;
try
{
mm.To.Clear();
mm.To.Add(arrMails[i]);
}
catch (FormatException fe)
{
//记录错误发送的邮件
arrErrorMails.Add(arrMails[i]);
//MessageBox.Show("有非邮件格式,请修正后重试!", MSG_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
try
{
smtp.Send(mm);
//MessageBox.Show("发送成功!", MSG_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information);
arrSuccessMails.Add(arrMails[i]);
iSuccessCount++;
//发现有的发10个以上,就会失败
if (iSuccessCount > 0 && iSuccessCount % 10 == 0)
{
System.Threading.Thread.Sleep(5 * 1000); //停几秒再发
}
}
catch (Exception ex)
{
//Message = "不允许使用邮箱名称。 服务器响应为: Requested action not taken: Local user only,smtp2,DNGowEDpelx8+SBQp+ZBAQ--.852S2 1344338303"
//System.Net.Mail.SmtpException: 事务失败。 服务器响应为: MI:STC 0,smtp3,DdGowECJLV0A+iBQ3TEQFA--.773S2 1344338432
//正在处理错误。 服务器响应为: MI:SFQ 0,smtp3,DdGowEC5mldx_CBQsc4QFA--.106S3 1344339057 http://mail.163.com/help/help_spam_16.htm?ip=111.161.77.192&hostid=smtp3&time=1344339057
//MessageBox.Show("发送错误信息:" + ex.Message, MSG_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information);
//Message = "邮箱不可用。 服务器响应为: User not found: abird70@163.com"
for (int m = 0; m < m_Setting.InterimLimitCode.Count; m++)
{
//网易的
if (ex.Message.IndexOf("服务器响应为: " + m_Setting.InterimLimitCode[m]) > 1)
{
System.Threading.Thread.Sleep(30 * 1000);
}
}
arrFaileErrorMails.Add(arrMails[i]);
//System.Threading.Thread.Sleep(5 * 1000);
}
}
string strResult = "";
frmMailResult frmResult = null;
this.pnStatus.Visible = false ;
if (iTotalCount == iSuccessCount)
{
strResult = string.Format("共有{0}封邮件,全部发送成功!", iTotalCount.ToString());
if (MessageBox.Show(strResult + "\r\n是否查看详细反馈信息?", MSG_TITLE, MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
{
frmResult = new frmMailResult(strResult,arrFaileErrorMails,arrSuccessMails);
frmResult.ShowDialog();
frmResult.Dispose();
}
return true;
}
else
{
strResult = string.Format("共有{0}封邮件,其中发送成功数{1},有{2}封邮件发送失败!", iTotalCount.ToString(), iSuccessCount.ToString(), (iTotalCount - iSuccessCount).ToString());
if (MessageBox.Show(strResult + "\r\n是否查看详细反馈信息?", MSG_TITLE, MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
{
frmResult = new frmMailResult(strResult, arrFaileErrorMails, arrSuccessMails);
frmResult.ShowDialog();
frmResult.Dispose();
}
return false;
}
#endregion 实现...
}
else
{
#region 实现...
try
{
mm.To.Add(ReplaceMailList(txtTO.Text));
if (txtCC.Text.Trim() != "")
{
mm.CC.Add(ReplaceMailList(txtCC.Text));
}
if (txtBCC.Text.Trim() != "")
{
mm.Bcc.Add(ReplaceMailList(txtBCC.Text));
}
}
catch (FormatException fe)
{
MessageBox.Show("有非邮件格式,请修正后重试!", MSG_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information);
return false;
}
try
{
smtp.Send(mm);
MessageBox.Show("发送成功!", MSG_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information);
return true;
}
catch (Exception ex)
{
MessageBox.Show("发送错误信息:" + ex.Message, MSG_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information);
txtTO.Focus();
return false;
}
#endregion 实现...
}
#endregion 实现...
}
相关源码下载信息请访问:
http://blog.csdn.net/flygoldfish
声明:本文版权为周方勇所有,欢迎转载,请保留完整的内容及出处。
flygoldfish@163.com