一、程序来发送邮件必要信息
Smtp服务器:发送邮件的服务器,如常见的smtp.163.com、smtp.qq.com,不同的服务商,发送邮件的服务器也不相同
账号:发送邮件的邮箱账号
密码:邮箱密码或授权码(注:当你在程序中使用邮箱密码进行发邮件,发现无法发送等问题,就要考虑邮箱是否开启了SMTP权限,是不是需 要使用授权码进行发邮件,像qq、163邮箱,这些邮箱是需要先开启SMTP发送邮件的权限,当开启后,会产生一个授权码,这时第三方就可以使用邮件账号加授权码来实现发送邮件功能)
端口:25、587和465。不同的端口号用于不同的目的,因此在配置邮箱的SMTP端口号时,需要选择适合您需求的端口号。
二、不同邮件服务商的支持协议的区别
| 邮箱 | smtp服务器 | 支持的协议(可能有遗漏) |
|---|---|---|
| gmail | smtp.gmail.com | TLS/ STARTTLS(TLS) |
| smtp.qq.com | SSL/TLS/ STARTTLS(TLS) | |
| foxmail | smtp.exmail.qq.com | SSL/TLS/ STARTTLS(TLS) |
| outlook | smtp-mail.outlook.com | STARTTLS(TLS) |
| 雅虎 | smtp.mail.yahoo.com | TLS/STARTTLS(TLS) |
| 网易163 | smtp.163.com | SSL/TLS |
| hotmail | smtp.live.com | STARTTLS(TLS) |
| icloud | smtp.mail.me.com | STARTTLS(TLS) |
| Yandex | smtp.yandex.ru | SSL/TLS/STARTTLS(SSL/TLS) |
| GMX | smtp.gmx.com | TLS/STARTTLS |
| 新浪 | smtp.sina.com | SSL/TLS/STARTTLS(SSL/TLS) |
| aol | smtp.aol.com | TLS/STARTTLS |
| rediff | smtp.rediffmail.com | SSL/TLS/STARTTLS(SSL/TLS) |
由于不同的协议,所以在选中开放的端口时要注意一般都是采用587端口作为开放端口,但是有的服务商不支持STARTTLS协议,所以就用25端口或者465端口。
三、邮件发送限制
| 邮件服务商 | 发送限制 | 收件人限制 |
|---|---|---|
| 网易企业邮箱 | 单个用户每天最多只能发送 1000 封邮件 | 单个邮件最多包含 500 个收件人邮箱地址 |
| 163VIP邮箱 | 每天限制最多能发送800封邮件 | 单个邮件最多包含 500 个收件人邮箱地址 |
| 163 、 126 、 yeah 的邮箱 | 每天发送限额为 50 封 | 一封邮件最多发送给 40 个收件人 |
| 尚易企业邮箱 | 一个 IP 一分钟最多发送 400 个邮件地址 | 一封邮件最多 200 个邮件地址(如果一封邮件包括 200 个收信人地址,一分钟最多不能超过 2 封邮件;如果一封邮件只有一个收信人地址 , 一分钟发送的邮件不能超过 6 封) |
| QQ邮箱(2G 的普通用户) | 每天最大发信量是 100 封 | |
| QQ邮箱(3G 会员、移动 QQ 、 QQ 行及 4G大肚邮) | 每天最大发信量是 500 封 | |
| Foxmail 免费邮箱 | 每天发送量限制为 50 封 | |
| Gmail邮箱 | 每天 500 封(新申请的邮箱,限制 50 封) | |
| 新浪邮箱(企业邮箱试用期) | 每天限制 80 封 | |
| 新浪免费邮箱 | 每天限制发送 50 封 | |
| 雅虎免费邮箱 | 每小时发送量限制为100封;每天发送量限制为 200 封 | |
| 阿里企业邮箱(免费版本) | 每天500封信 |
四、邮件发送方法
1、基于System.Net.Mail.MailMessage 发送邮件
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="email">收件人邮箱</param>
/// <param name="title">标题</param>
/// <param name="content">发送内容</param>
/// <returns></returns>
public static bool SendEmail(string email,string title,string content)
{
string _smtpServer = "smtp.163.com"; //SMTP服务器
string _userName = "test@163.com"; //邮箱
string _pwd = "test"; //密码或授权码
if(_smtpServer == "" || _userName == "" || _pwd == "") {
return false;
}
using(System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage()) {
/*
* msg.To.Add("b@b.com");可以发送给多人
*/
msg.To.Add(email); //设置收件人
/*
* msg.CC.Add("c@c.com");
* msg.CC.Add("c@c.com");可以抄送给多人
*/
/* 3个参数分别是 发件人地址(可以随便写),发件人姓名,编码*/
msg.From = new MailAddress(_userName,_userName,System.Text.Encoding.UTF8);
msg.Subject = title; //邮件标题
msg.SubjectEncoding = System.Text.Encoding.UTF8; //邮件标题编码
msg.Body = content; //邮件内容
msg.BodyEncoding = System.Text.Encoding.UTF8;//邮件内容编码
msg.IsBodyHtml = true; //是否是HTML邮件
msg.Priority = MailPriority.Normal; //邮件优先级
SmtpClient client = new SmtpClient(_smtpServer,587); //邮件服务器地址及端口号
client.EnableSsl = true; //ssl加密发送
client.DeliveryMethod = System.Net.Mail.SmtpDeliveryMethod.Network;
client.Credentials = new System.Net.NetworkCredential(_userName,_pwd); //邮箱账号 密码
client.Timeout = 6000; //6秒超时
try {
client.Send(msg); //发送邮件
client.Dispose(); //释放资源
return true;
} catch(System.Net.Mail.SmtpException ex) {
return false;
}
}
}
缺点:该方法如果采用163邮箱加密发送,会发送失败,需要设置 client.EnableSsl = false ,端口设置为25,因为System.Net.Mail只支持显式SSL(ExplicitSSL),但是不支持隐式SSL(Implicit SSL),所以会造成163邮箱发送超时的问题,可以使用下面的发送邮件函数来解决。
注:如果线上环境用的是阿里的服务器,阿里云为了反垃圾邮件,25端口是封掉的,也就是说,如果你要使用阿里服务器发送邮件,25端口是走不通的,必须使用其他端口发送邮件, 这个时候就要用到加密端口发送邮件。如果你的项目有发送邮件的功能,且在测试服务器上发邮件是正常的,部署到阿里云之后就不行了, 这个时候就要想到是不是服务器端口的问题。
2、基于System.Web.Mail 发送邮件(用于解决163邮箱加密发送超时问题,该函数微软已弃用,如果不是特殊情况,不推荐使用该函数)
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="emails">收件人的邮箱</param>
/// <param name="title">邮件标题</param>
/// <param name="content">邮件内容(支持Html)</param>
public static bool SendEmailBack(List<string> emails,string title,string content)
{
string _smtpServer = "smtp.163.com"; //发邮件smtp服务器名称
string _userEmail = "test@163.com"; //发送人邮箱地址
string _pwd = "test"; //发邮件邮箱的密码或授权码
System.Web.Mail.MailMessage _msg = new System.Web.Mail.MailMessage();
//邮件主题
_msg.Subject = title;
_msg.BodyFormat = System.Web.Mail.MailFormat.Html;
//邮件正文
_msg.Body = content;
//正文编码
_msg.BodyEncoding = Encoding.UTF8;
//优先级
_msg.Priority = System.Web.Mail.MailPriority.Normal;
//发件者邮箱地址
_msg.From = _userEmail;
//收件人收箱地址
string _toEmail = "";
emails.ForEach(s => { _toEmail += s + ","; });
//_msg.Cc = _toEmail.TrimEnd(','); //抄送
_msg.To = _toEmail.TrimEnd(','); //收件人
_msg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate","1");
//用户名
_msg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername",_userEmail);
//密码
_msg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword",_pwd);
//端口
_msg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport",465);
//是否ssl
_msg.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpusessl",true);
//Smtp服务器
System.Web.Mail.SmtpMail.SmtpServer = _smtpServer;
try {
System.Web.Mail.SmtpMail.Send(_msg);
return true;
} catch(SmtpException e) {
return false;
}
}
总结
显式SSL通过25端口连接 -> StartTLS(开始加密)-> 验证 -> 发送数据
隐式SSLStartSSL(开始加密) -> 连接 -> 验证 -> 发送数据
在采用邮件发送时,需要根据邮件服务商支持的协议,开放对应的端口