1、几种电子邮件系统组成
传统电子邮件系统
一个传统电子邮件系统由以下几个部分组成
- UA(用户代理)
- 邮箱服务器
- 电子邮件协议
- 邮件发送协议(SMTP)与邮件接受协议(POP3,IMAP)
用户代理 UA (User Agent)
定义:用户代理 UA 就是用户与电子邮件系统的接口,是电子邮件客户端软件。通常是用户计算机中的一个程序
功能:撰写、显示、处理和通信。
邮箱服务器
功能:收发电子邮件
邮件服务器使用客户-服务器方式工作,同时需要使用两种协议:邮件发送协议和邮件接收协议。发送协议用于UA向服务器或者服务器向服务器发送邮件,接收邮件用于UA从服务器读取邮件。
同时邮件服务器必须能够同时充当客户与服务器。当A发送邮件到B,A为客户;当A从B接收邮件,A为服务器。
基于万维网的电子邮件系统
2、电子邮件协议
SMTP
smtp的通信有三个阶段
- 连接建立
- 邮件传送
- 连接释放
连接建立
1.当SMTP客户端每隔一定时间对邮件缓存扫描一次,如发现有邮件,就使用SMTP的熟知端口号25与接收方的邮件服务器的SMTP服务器建立TCP连接。
2.接收方SMTP服务器发出“220 Service ready"告诉客户端它已经准备好接收邮件。
3.客户发送HELO报文,附上发送方的主机名。如果服务器可以接收,则发送“250 OK",否则发送”421 service not available“
SMTP不使用中间的邮件服务器,TCP建立总是在发送方与接收方直接建立。
邮件传送
1.客户发送MAIL FROM报文介绍报文的发送者。它包括发送人的邮件地址(邮箱名和域名,如house@qq)。这个步骤是必要的:因为可以给服务器在返回差错或报文时的返回邮件地址 。
2.服务器响应代码250(请求命令完成)或其他适当的代码
3.客户发送一个或多个RCPT命令,包括收件人的邮件地址,RCPT命令的作用是 : 先弄清接收方系统是否已经准备好接收邮件的准备,然后才发送邮件,这样做视为了避免浪费通信资源,不至于发送了很长的邮件以后才知道是因地址错误 。
4.服务器响应代码250或其他适当的代码。
5.客户发送DATA报文对报文的传送进行初始化,DATA命令表示要开始传送邮件的内容了。
6.服务器响应代码"354 Start mail input: end with <CRLF>.<CRLF>"或其他适当的报文(如421 服务器不可用,500 命令无法识别)。
7.客户用连续的行发送报文的内容。每一行的行结束时输入 <CRLF>.<CRLF> ,即回车换行.回车换行,表示邮件内容结束。
8.服务器响应代码(250 请求命令完成)或其他适当的代码。
值得注意的是:虽然SMTP使用TCP连接试图使邮件的传送可靠,但它并不能保证不丢失邮件。也就是说,使用SMTP传送邮件只能说可以可靠地传送接收方的邮件服务器,在往后的情况就不知道了。接收方的邮件服务器也许会出故障,使收到的服务器全部丢失(在收件人读取信件之前)。
连接释放
1.客户发送QUIT命令。
2.服务器响应221(TCP服务关闭)
局限
原生SMTP只能传输ASCII码,最多7B,可不传输2进制文件。明文传输。
POP3
POP3采用C/S的工作方式。在接收邮件的用户PC机中的用户代理UA必须运行POP3的客户程序,而在收件人所连接的ISP的邮件服务器中则运行POP的服务器程序。POP服务器只有在用户输入鉴别信息(用户名+口令)后,才允许对方对邮箱进行读取 。
POP3有 两种工作方式 :删除方式和保存方式。
删除方式就在每一次读取邮件后就把邮箱中的这个邮件删除,用户只能读取一次
保存方式就是在读取邮件后,邮件仍然在服务器中保存,用户可读取多次,该方式是通过对之前的POP3工作方式(即删除)的缺点进行弥补,对功能进行扩充。
IMAP
在使用IMAP时,用户的PC机上运行IMAP客户程序,然后与接收方的邮件服务器上的IMAP服务器程序建立TCP连接。 POP3不允许用户在邮件服务器上整理自己的邮件,用户在服务器上不能不同的文件夹,POP3也不允许用户在下载邮件之前读取邮件的部分内容,而IMAP则克服了这些POP3的缺点,说白了就是POP3协议不太愿意让用户直接操作服务器,而IMAP正好客户了这些缺点 。
IMAP4提供了以下功能( 这些功能POP3则没有 ):
1.用户在下载邮件之前可以检查邮件的首部。
2.用户在下载邮件之前可以用特定的字符串搜索电子邮件的内容。
3.用户可以部分地下载电子邮件。
4.用户可以在邮件服务器上创建、删除邮箱,或对邮箱重命名。(IMAP是双向的,可以同步本地修改到服务端;POP只能同步服务端到本地)
5.为了存放电子邮件,用户可以在文件夹中创建分层次的邮箱。
补充
为了改变SMTP只能传输ASCII码的缺点,提出了MIME,MIME没有改变SMTP,而是继续采用现有的邮件编码,但增加了邮件主题的结构,定义了传送非ASCII码的编码规则
3、telnet实验电子邮件协议
SMTP
POP3
4、java mail
添加javax.mail依赖
public class Main{
private static String charset = "utf-8";
private static final String user = "xxxxx@qq.com";
private static final String pass = "xxx";//授权码
public static void main(String[] args) throws IOException, MessagingException {
Session session = getSession();
MimeMessage email = getEmail(session);
Transport transport = session.getTransport();
transport.connect(user, pass);
transport.sendMessage(email, email.getAllRecipients());
transport.close();
}
private static MimeMessage getEmail(Session session) throws MessagingException, UnsupportedEncodingException {
MimeMessage mimeMessage = new MimeMessage(session);
mimeMessage.setRecipient(Message.RecipientType.TO, new InternetAddress("xxx@qq.com", "he", charset));
mimeMessage.setText("hello world",charset);
mimeMessage.setSentDate(new Date());
mimeMessage.setContent("hello world", "text/html;charset=utf-8");
mimeMessage.setFrom(new InternetAddress("xxx@qq.com", "she", charset));
mimeMessage.setSubject("TEST邮件主题", "UTF-8");
mimeMessage.saveChanges();
return mimeMessage;
}
private static Session getSession() {
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp"); // 使用的协议(JavaMail规范要求)
props.setProperty("mail.smtp.host", "smtp.qq.com"); // 发件人的邮箱的 SMTP 服务器地址
/* 开启了SSL认证的SMTP连接
props.setProperty("mail.smtp.auth", "true"); // 需要请求认证
final String smtpPort = "465";
props.setProperty("mail.smtp.port", smtpPort);
props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.setProperty("mail.smtp.socketFactory.fallback", "false");
props.setProperty("mail.smtp.socketFactory.port", smtpPort);
*/
Session session = Session.getInstance(props);
session.setDebug(true);
return session;
}
}
springboot:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
spring:
# 发送QQ邮件配置
mail:
host: smtp.qq.co
protocol: smtp
port: 465
username: xxxx@qq.com. #邮箱地址
password: xxxx #授权码
properties: # 配置以SSL的方式发送, 这个需要使用这种方式并且端口是465
mail:
smtp:
auth: true
ssl:
enable: true
socketFactory:
class: com.sun.mail.util.MailSSLSocketFactory
fallback: false
debug: true
工具类网上随便找一个,或者参考spring官网
参考文章
计算机网络 电子邮件
在telnet登录并使用SMTP和POP收发邮件(QQ邮箱)
基于JavaMail的Java邮件发送:简单邮件发送
spring官网