原理

组成角色

电子邮件系统由 2 部分组成:

  • 用户客户端(user client):是用户进行阅读、回复、转发、保存和撰写邮件的工具,即各种邮箱软件,一般运行在用户的 PC 上
  • 邮件服务器(mail server):邮件服务器可以与其他邮件服务器通信,由邮件服务商维护

协议

邮件服务其提供以下 3 种协议的接口:

  • SMTP(Simple Mail Transfer Protocol):发送邮件使用 SMTP 协议,一般有 2 中情况:
    1. 发送邮件时,客户端首先会将邮件通过 SMTP 发送给邮件服务器,取决于客户端的 SMTP 配置
    2. 如果接收到邮件的邮件服务器与目的邮件地址的邮件服务器不同,邮件服务器会再次将邮件通过 SMTP 发送给目的邮件地址的邮件服务器
    3. SMTP 协议不会验证发送方,因此产生了 SPF, DKIM, DMARC 等验证方案
  • POP3(Post Office Protocol-Version 3):用于取回、删除邮件服务器中的报文
  • IMAP(Internet Mail Access Protocol):类似与POP3,但可以在邮件服务器中创建远程文件夹并为报文指派文件夹

SMTP 默认端口 25,POP3 默认端口 110,IMAP 默认端口 143,不同邮件服务商可能会有区别,需要自己去查询。例如这里可以查看 163 邮件服务器提供 3 种协议与对应的地址和端口: http://help.163.com/10/0731/11/6CTUBPT300753VB8.html

一次邮件发送过程

假设有用户 A 和 B,A 的邮件地址是 amail@outlook.com,B 的邮件地址是 bmail@gmail.com,现在 A 向 B 发送邮件,其过程为:

  1. A 使用 outlook 之类的邮箱客户端 (user client) 写好邮件,填写对方的 Email 地址 (bmail@gmail.com),点击发送
  2. 邮箱客户端通过 SMTP 协议把邮件推送到 outlook 的邮件服务器 (mail server),邮件服务器将邮件加入到自身维护的报文队列
  3. outlook 通过 DNS 查询域名 gmail.com MX 记录,获取 gamil 邮件服务的地址,然后通过 SMTP 将邮件推送到 gmail 的邮件服务器中
  4. B 使用邮箱客户端通过 POP3 或者 IMAP 协议从 gmail 的邮件服务器中拉取发给自己的邮件
A[user client] ---报文--> [outlook mail server 的报文队列] ---报文--> [B 在 gmail server上的用户邮箱]  ---报文-->  [user client]B
                  SMTP                                        SMTP                                      POP3/IMAP

邮件报文格式与MIME

  1. 报文首部
  2. \r\n
  3. 报文体
From: alice@crepes.fr
To: bob@hamburger.edu
Subject: Searching for the meaning of life

<以ACSII格式表示的报文体>

配置SMTP(端口25)服务器地址,如163.com请使用smtp.163.com,为了证明自己,需自己的邮件地址和密码

配置POP3(端口110),为了证明自己,需自己的邮件地址和密码

实践

SMTP 服务

由以上内容可知,如果需要发送邮件,必须要将邮件通过 SMTP 协议发送给 SMTP 服务,由 SMTP 服务进行之后的操作。

我们可以启动自己的 SMTP 服务

sudo python -m smtpd -n -c DebuggingServer localhost:25

postfix

sendmail

客户端发送代码

  • java: https://www.baeldung.com/java-email