参考文献

邮件的基本概念

邮件服务器

  • 邮件服务器是一种用来负责电子邮件收发管理的设备,同时也是电子邮件系统中的核心内容.
  • 邮件服务器是有发送邮件SMTP服务器和接收邮件POP3服务器协同工作,并且为用户提供接收邮件的功能.
  • 邮件服务器比一般的免费邮箱更加安全,一直被企业公司使用.

电子邮箱

  • 电子邮箱也称为E-mail地址,比如xx@qq.com、xx@163.com。用户能通过E-mail地址标识自己发送的电子邮件,同时也可以通过这个地址接收别人发来的电子邮件。
  • 电子邮箱需要到邮件服务器进行申请,也就是说,电子邮箱其实就是用户在邮件服务器上申请的账户。邮件服务器会把接收到的邮件保存到为该账户所分配的邮箱空间中,用户通过用户名密码登录到邮件服务器查收该地址已经收到的邮件。一般来讲,邮件服务器为用户分配的邮箱空间是有限的。

邮件客户端

  • 邮件客户端就是我们平常在上面进行邮件发送的网站或者应用,比如常见的FoxMail、雷鸟、outlook、163、mesign等;
  • 通常使用IMAP/APOP/POP3/SMTP协议收发电子邮件的软件都可以统称邮件客户端;
  • 因为这些客户端可以帮助用户把邮件发送给SMTP邮件服务器,也可以从POP3/IMAP邮件服务器读取用户的电子邮件

邮件传输协议

  • 电子邮件需要在邮件客户端和邮件服务器之间,以及两个邮件服务器之间进行邮件传递,那就必须遵守规则,这个规则就是邮件传输协议.
SMTP协议
  • (Simple Mail Transfer Protocol)简单邮件传输协议(默认端口25)
  • 它定义了邮件客户端软件和SMTP邮件服务器之间,以及两台SMTP邮件服务器之间的通信规则.
POP/POP3协议
  • (Post Office Protocol)邮件接收协议(默认端口110)
  • 当用户计算机与支持POP协议的电子邮件服务器连接时,把存储在该服务器的电子邮箱中的邮件准确无误地下载到用户的计算机中
  • POP3属于离线式协议,即不能对邮件进行在线操作,必须下载到本地才能进行处理。POP协议已发展到第三版,称作POP3。
  • POP3与SMTP一样都是请求响应协议,命令与响应也都是用NVT ASCII格式的文本表示。POP3响应由一个状态码和其后的附加信息组成,只有两种状态码:“+OK”(正确)和"-ERR"(失败)
IMAP协议
  • (Internet Message Access Protocol)Internet消息访问协议(默认端口143)
  • 它是对POP3协议的一种扩展,也是定义了邮件客户端软件和IMAP邮件服务器的通信规则,它运行在TCP/IP协议之上,与POP3的主要区别是这个IMAP协议可以在线操作,可以不用把用户的所有邮件下载,可以通过客户端直接对服务器上的邮件在线操作.

常见的邮箱服务器的POP3/SMTP地址端口

邮箱名称 POP3服务器地址 SMTP服务器地址
163.com pop.163.com(端口:110) smtp.163.com(端口:25)
126.com pop.126.com(端口:110) smtp.126.com(端口:25)
gmail(google.com) pop.gmail.com(SSL启用端口:995) smtp.gmail.com(SSL启用 端口:587)

阿里邮箱

协议 服务器地址 服务器端口号(常规) 服务器端口号(加密)
POP3 pop.qiye.aliyun.com 110 995
IMAP imap.qiye.aliyun.com 143 993
SMTP smtp.qiye.aliyun.com 25 465
  • 老地址
协议 服务器地址 服务器端口号(常规) 服务器端口号(加密)
POP3 pop3.mxhichina.com 110 995
IMAP imap.mxhichina.com 143 993
SMTP smtp.mxhichina.com 25 465

常见失败编码速查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
421
  421 HL:REP   该IP发送行为异常,存在接收者大量不存在情况,被临时禁止连接。请检查是否有用户发送病毒或者垃圾邮件,并核对发送列表有效性;
  421 HL:ICC   该IP同时并发连接数过大,超过了网易的限制,被临时禁止连接。请检查是否有用户发送病毒或者垃圾邮件,并降低IP并发连接数量;
  421 HL:IFC   该IP短期内发送了大量信件,超过了网易的限制,被临时禁止连接。请检查是否有用户发送病毒或者垃圾邮件,并降低发送频率;
  421 HL:MEP   该IP发送行为异常,存在大量伪造发送域域名行为,被临时禁止连接。请检查是否有用户发送病毒或者垃圾邮件,并使用真实有效的域名发送;
450
  450 MI:CEL 发送方出现过多的错误指令。请检查发信程序;
  450 MI:DMC 当前连接发送的邮件数量超出限制。请减少每次连接中投递的邮件数量;
  450 MI:CCL 发送方发送超出正常的指令数量。请检查发信程序;
  450 RP:DRC 当前连接发送的收件人数量超出限制。请控制每次连接投递的邮件数量;
  450 RP:CCL 发送方发送超出正常的指令数量。请检查发信程序;
  450 DT:RBL 发信IP位于一个或多个RBL里。请参考http://www.rbls.org/关于RBL的相关信息;
  450 WM:BLI 该IP不在网易允许的发送地址列表里;
  450 WM:BLU 此用户不在网易允许的发信用户列表里;
451
  451 DT:SPM ,please try again
邮件正文带有垃圾邮件特征或发送环境缺乏规范性,被临时拒收。请保持邮件队列,两分钟后重投邮件。需调整邮件内容或优化发送环境
  451 Requested mail action not taken: too much fail authentication
登录失败次数过多,被临时禁止登录。请检查密码与帐号验证设置;
  451 RP:CEL 发送方出现过多的错误指令。请检查发信程序;
  451 MI:DMC 当前连接发送的邮件数量超出限制。请控制每次连接中投递的邮件数量;
  451 MI:SFQ 发信人在15分钟内的发信数量超过限制,请控制发信频率;
  451 RP:QRC 发信方短期内累计的收件人数量超过限制,该发件人被临时禁止发信。请降低该用户发信频率;
  •451 Requested action aborted: local error in processing 系统暂时出现故障,请稍后再次尝试发送;
500
  500 Error: bad syntaxU 发送的smtp命令语法有误;
  550 MI:NHD HELO命令不允许为空;
  550 MI:IMF 发信人电子邮件地址不合规范。请参考http://www.rfc-editor.org/关于电子邮件规范的定义;
  550 MI:SPF 发信IP未被发送域的SPF许可。请参考http://www.openspf.org/关于SPF规范的定义;
  550 MI:DMA 该邮件未被发信域的DMARC许可。请参考http://dmarc.org/关于DMARC规范的定义;
  550 MI:STC 发件人当天的连接数量超出了限定数量,当天不再接受该发件人的邮件。请控制连接次数;
  550 RP:FRL 网易邮箱不开放匿名转发(Open relay);
  550 RP:RCL 群发收件人数量超过了限额,请减少每封邮件的收件人数量;
  550 RP:TRC 发件人当天内累计的收件人数量超过限制,当天不再接受该发件人的邮件。请降低该用户发信频率;
  550 DT:SPM 邮件正文带有很多垃圾邮件特征或发送环境缺乏规范性。需调整邮件内容或优化发送环境;
  550 Invalid User 请求的用户不存在;
  550 User in blacklist 该用户不被允许给网易用户发信;
  550 User suspended 请求的用户处于禁用或者冻结状态;
  550 Requested mail action not taken: too much recipient 群发数量超过了限额;
552
  552 Illegal Attachment 不允许发送该类型的附件,
包括以.uu .pif .scr .mim .hqx .bhx .cmd .vbs .bat .com .vbe .vb .js .wsh等结尾的附件;
  552 Requested mail action aborted: exceeded mailsize limit 发送的信件大小超过了网易邮箱允许接收的最大限制;
-553
  553 Requested action not taken: NULL sender is not allowed 不允许发件人为空,请使用真实发件人发送;
  553 Requested action not taken: Local user only SMTP类型的机器只允许发信人是本站用户;
  553 Requested action not taken: no smtp MX only MX类型的机器不允许发信人是本站用户;
  553 authentication is required SMTP需要身份验证,请检查客户端设置;
-554
  554 DT:SPM 发送的邮件内容包含了未被许可的信息,或被系统识别为垃圾邮件。请检查是否有用户发送病毒或者垃圾邮件;
  554 DT:SUM 信封发件人和信头发件人不匹配;
  554 IP is rejected, smtp auth error limit exceed 该IP验证失败次数过多,被临时禁止连接。请检查验证信息设置;
  554 HL:IHU 发信IP因发送垃圾邮件或存在异常的连接行为,被暂时挂起。请检测发信IP在历史上的发信情况和发信程序是否存在异常;
  554 HL:IPB 该IP不在网易允许的发送地址列表里;
  554 MI:STC 发件人当天内累计邮件数量超过限制,当天不再接受该发件人的投信。请降低发信频率;
  554 MI:SPB 此用户不在网易允许的发信用户列表里;
  554 IP in blacklist 该IP不在网易允许的发送地址列表里。

常用Multipart类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
MIME邮件中各种不同类型的内容是分段存储的,各个段的排列方式、位置信息都通过Content-Type域的multipart类型来定义。
multipart类型主要有三种子类型:mixed、alternative、related
①:multipart/mixed类型:
如果一封邮件中含有附件,那邮件的Content-Type域中必须定义multipart/mixed类型,邮件通过multipart/mixed类型中定义
的boundary标识将附件内容同邮件其它内容分成不同的段。基本格式如下:
Content-Type:multipart/mixed;
boundary="{分段标识}"
②:multipart/alternative类型:
MIME邮件可以传送超文本内容,但出于兼容性的考虑,一般在发送超文本格式内容的同时会同时发送一个纯文本内容的副本,如果邮件中同时存在
纯文本和超文本内容,则邮件需要在Content-Type域中定义multipart/alternative类型,邮件通过其boundary中分段标识将纯文本、超文
本和邮件的其它内容分成不同的段。基本格式如下:
Content-Type:multipart/alternative;
boundary="{分段标识}"
③:multipart/related类型:
MIME邮件中可以携带各种附件外,还可以将其它内容以内嵌资源的方式存储在邮件中。比如我们在发送html格式的邮件内容时,可能使用图像作
为html的背景,html文本会被存储在alternative段中,而作为背景的图像则会存储在multipart/related类型定义的段中。基本格式如下:
Content-Type:multipart/related;
type="multipart/alternative";
boundary="{分段标识}"
multipart类型的boundary属性
multipart的子类型中都定义了各自的boundary属性,邮件使用这些boundary中定义的字符串作为标识,将邮件内容分成不同的段,段体内
的每个子段以“--”+boundary行开始,父段则以“--”+boundary+“--”行结束,不同段之间用空行分隔。

Jakarta Mailproperties扩展配置

配置名称 配置值类型 说明
mail.smtp.user String SMTP 的默认用户名
mail.smtp.host String 要连接的 SMTP 服务器
mail.smtp.port int 要连接的 SMTP 服务器端口,如果 connect() 方法没有明确指定一个。默认为 25
mail.smtp.connectiontimeout int 以毫秒为单位的套接字连接超时值。这个超时是由 java.net.Socket 实现的。默认为无限超时
mail.smtp.timeout int 以毫秒为单位的套接字读取超时值。这个超时是由 java.net.Socket 实现的。默认为无限超时
mail.smtp.writetimeout int 以毫秒为单位的套接字写入超时值。此超时是通过对每个连接使用 java.util.concurrent.ScheduledExecutorService 来实现的,
该服务会在超时到期时安排线程关闭套接字。因此,使用此超时的开销是每个连接一个线程。默认为无限超时。
mail.smtp.from String 用于 SMTP MAIL 命令的电子邮箱地址。这将设置信封返回地址。默认为 msg.getFrom() 或 InternetAddress.getLocalAddress()。
注意:mail.smtp.user 以前用于此目的
mail.smtp.localhost String SMTP HELO 或 EHLO 命令中使用的本地主机名。默认为InetAddress.getLocalHost().getHostName().
如果您的 JDK 和名称服务配置正确,则通常不需要设置
mail.smtp.localaddress String 创建 SMTP 套接字时要绑定到的本地地址(主机名)。默认为 Socket 类选择的地址。通常不需要设置,
但对于选择要绑定到的特定本地地址很重要的多宿主主机很有用
mail.smtp.localport int 创建 SMTP 套接字时要绑定到的本地端口号。默认为 Socket 类选择的端口号
mail.smtp.ehlo boolean 如果为 false,则不要尝试使用 EHLO 命令登录。默认为真。通常 EHLO 命令失败将回退到 HELO 命令;
此属性仅适用于未正确使 EHLO 失败 或未正确实现 EHLO 的服务器
mail.smtp.auth boolean 如果为 true,则尝试使用 AUTH 命令对用户进行身份验证。默认为假
mail.smtp.auth.mechanisms String 如果设置,则列出要考虑的身份验证机制,以及考虑它们的顺序。只会使用服务器支持和当前实现支持的机制。
默认为"LOGIN PLAIN DIGEST-MD5 NTLM",包括当前实现支持的所有认证机制,除了 XOAUTH2
mail.smtp.auth.login.disable boolean 如果为 true,则阻止使用该AUTH LOGIN命令。默认为假
mail.smtp.auth.plain.disable boolean 如果为 true,则阻止使用该AUTH PLAIN命令。默认为假
mail.smtp.auth.digest-md5.disable boolean 如果为 true,则阻止使用该AUTH DIGEST-MD5命令。默认为假
mail.smtp.auth.ntlm.disable boolean 如果为 true,则阻止使用该AUTH NTLM命令。默认为假
mail.smtp.auth.ntlm.domain String NTLM 身份验证域
mail.smtp.auth.ntlm.flags int NTLM 协议特定标志。有关详细信息,请参阅 http://curl.haxx.se/rfc/ntlm.html#theNtlmFlags。
mail.smtp.auth.xoauth2.disable boolean 如果为 true,则阻止使用该AUTHENTICATE XOAUTH2命令。由于 OAuth 2.0 协议需要特殊的访问令牌而不是密码,因此默认情况下
禁用此机制。通过将此属性显式设置为“false”或将“mail.smtp.auth.mechanisms”属性设置为“XOAUTH2”来启用它
mail.smtp.submitter String 要在 MAIL FROM 命令的 AUTH 标记中使用的提交者。通常由邮箱中继用于传递有关邮箱原始提交者的信息。
另请参阅 的setSubmitter 方法SMTPMessage。邮箱客户端通常不使用它
mail.smtp.dsn.notify String RCPT 命令的 NOTIFY 选项。NEVER 或 SUCCESS、FAILURE 和 DELAY(以逗号分隔)的某种组合
mail.smtp.dsn.ret String MAIL 命令的 RET 选项。FULL 或 HDRS
mail.smtp.allow8bitmime boolean 如果设置为 true,并且服务器支持 8BITMIME 扩展,则使用“quoted-printable”或“base64”编码的邮箱的文本部分
如果遵循 8bit 文本的 RFC2045 规则,则将转换为使用“8bit”编码
mail.smtp.sendpartial boolean 如果设置为 true,并且消息具有一些有效地址和一些无效地址,则无论如何都要发送消息,并使用 SendFailedException 报告部分失败。
如果设置为 false(默认值),则如果收件人地址无效,则不会将邮箱发送给任何收件人
mail.smtp.sasl.enable boolean 如果设置为 true,则尝试使用 javax.security.sasl 包来选择登录的身份验证机制。默认为假
mail.smtp.sasl.mechanisms String 要尝试使用的 SASL 机制名称的空格或逗号分隔列表
mail.smtp.sasl.authorizationid String 在 SASL 身份验证中使用的授权 ID。如果未设置,则使用身份验证 ID(用户名)
mail.smtp.sasl.realm String 用于 DIGEST-MD5 身份验证的领域
mail.smtp.sasl.usecanonicalhostname boolean 如果设置为 true,则返回的规范主机名将 InetAddress.getCanonicalHostName 传递给 SASL 机制,而不是用于连接的主机名。默认为假
mail.smtp.quitwait boolean 如果设置为 false,则发送 QUIT 命令并立即关闭连接。如果设置为 true(默认值),则导致传输等待对 QUIT 命令的响应
mail.smtp.quitonsessionreject boolean 如果设置为 false(默认值),会话发起拒绝时不发送 QUIT 命令并立即关闭连接。
如果设置为 true,则导致传输在关闭连接之前发送 QUIT 命令
mail.smtp.reportsuccess boolean 如果设置为 true,则会导致传输SMTPAddressSucceededException 为每个成功的地址包含一个 。还要注意 ,
即使所有地址都正确并且消息已成功发送,这将导致SendFailedException 从sendMessage方法中 抛出 a SMTPTransport
mail.smtp.socketFactory SocketFactory 如果设置为实现该javax.net.SocketFactory接口的类,则 该类将用于创建 SMTP 套接字。请注意,这是一个类的实例,而不是名称,并且必须使用put方法而不是setProperty方法来设置
mail.smtp.socketFactory.class String 如果设置,则指定实现javax.net.SocketFactory接口的类的名称 。此类将用于创建 SMTP 套接字
mail.smtp.socketFactory.fallback boolean 如果设置为 true,则无法使用指定的套接字工厂类创建套接字将导致使用java.net.Socket该类创建套接字。默认为真
mail.smtp.socketFactory.port int 指定使用指定套接字工厂时要连接的端口。如果未设置,将使用默认端口
mail.smtp.ssl.enable boolean 如果设置为 true,则默认使用 SSL 连接并使用 SSL 端口。“smtp”协议默认为 false,“smtps”协议默认为 true
mail.smtp.ssl.checkserveridentity boolean 如果设置为 true,请检查RFC 2595指定的服务器标识 。这些基于服务器证书内容的额外检查旨在防止中间人攻击。默认为假
mail.smtp.ssl.trust String 如果设置,并且未指定套接字工厂,则启用 MailSSLSocketFactory. 如果设置为“*”,则所有主机都是可信的。如果设置为以空格分隔的主机列表,则这些主机是可信的。否则,信任取决于服务器提供的证书
mail.smtp.ssl.socketFactory SSLSocketFactory 如果设置为扩展 javax.net.ssl.SSLSocketFactory类的类,则此类将用于创建 SMTP SSL 套接字。请注意,这是一个类的实例,而不是名称,并且必须使用put方法而不是setProperty方法来设置
mail.smtp.ssl.socketFactory.class String 如果设置,则指定扩展javax.net.ssl.SSLSocketFactory类的类的名称 。此类将用于创建 SMTP SSL 套接字
mail.smtp.ssl.socketFactory.port int 指定使用指定套接字工厂时要连接的端口。如果未设置,将使用默认端口
mail.smtp.ssl.protocols String 指定将为 SSL 连接启用的 SSL 协议。属性值是该javax.net.ssl.SSLSocket.setEnabledProtocols方法可接受的以空格分隔的标记列表
mail.smtp.ssl.ciphersuites String 指定将为 SSL 连接启用的 SSL 密码套件。属性值是该javax.net.ssl.SSLSocket.setEnabledCipherSuites方法可接受的以空格分隔的标记列表
mail.smtp.starttls.enable boolean 如果为 true,则启用该STARTTLS命令(如果服务器支持)在发出任何登录命令之前将连接切换到受 TLS 保护的连接。
如果服务器不支持 STARTTLS,则连接继续而不使用 TLS;mail.smtp.starttls.required 如果不支持 STARTTLS,
请查看失败的 属性。请注意,必须配置适当的信任库,以便客户端信任服务器的证书。默认为假
mail.smtp.starttls.required boolean 如果为 true,则需要使用该STARTTLS命令。如果服务器不支持 STARTTLS 命令,或者命令失败,connect 方法就会失败。默认为假
mail.smtp.proxy.host String 指定将用于连接到邮箱服务器的 HTTP Web 代理服务器的主机名
mail.smtp.proxy.port String 指定 HTTP Web 代理服务器的端口号。默认为端口 80
mail.smtp.proxy.user String 指定用于向 HTTP Web 代理服务器进行身份验证的用户名。默认情况下,不进行身份验证
mail.smtp.proxy.password String 指定用于向 HTTP Web 代理服务器进行身份验证的密码。默认情况下,不进行身份验证
mail.smtp.socks.host String 指定将用于连接到邮箱服务器的 SOCKS5 代理服务器的主机名
mail.smtp.socks.port String 指定 SOCKS5 代理服务器的端口号。仅当代理服务器未使用标准端口号 1080 时才需要使用此选项
mail.smtp.mailextension String 附加到 MAIL 命令的扩展字符串。扩展字符串可用于指定标准 SMTP 服务扩展以及特定于供应商的扩展。通常,
应用程序应使用该 SMTPTransport 方法supportsExtension 来验证服务器是否支持所需的服务扩展。
请参阅RFC 1869 和其他定义特定扩展的 RFC
mail.smtp.userset boolean 如果设置为true,则在isConnected方法中使用RSET 命令而不是NOOP 命令。在某些情况下,sendmail 在多次 NOOP 命令后响应会很慢;使用 RSET 避免了这个 sendmail 问题。默认为假
mail.smtp.noop.strict boolean 如果设置为 true(默认值),则坚持来自 NOOP 命令的 250 响应代码以指示成功。该isConnected方法使用 NOOP 命令 来确定连接是否仍然有效。一些较旧的服务器在成功时返回错误的响应代码,一些服务器根本不执行 NOOP 命令,因此总是返回失败代码。
将此属性设置为 false 以处理以这种方式损坏的服务器。通常,当服务器超时连接时,它会发送 421 响应代码,客户端将其视为对其发出的下一个命令的响应。某些服务器在连接超时时发送错误的失败响应代码。在处理以这种方式损坏的服务器时,不要将此属性设置为 false