使用java语言基于SMTP协议手写邮件客户端
使用java语言基于SMTP协议手写邮件客户端
1. 说明
电子邮件是互联网上常见的应用,他是互联网早期的产品,直至今日依然受到广大用户的喜爱(在中国可能因为文化背景不同,电子邮件只在办公的时候常用)。
电子邮件系统由以下几个部分组成:
- 用户代理
- 邮件服务器
- 邮件传输协议
总所周知,目前市面上流行的电子邮箱有qq邮箱,163邮箱等,我们可以去申请一个qq邮箱或者163邮箱,原因是因为腾讯和网易提供了邮件服务器。
同时我们也知道我们不仅仅可以通过qq邮箱的官方客户端收发邮件,而且可以通过其他客户端登入qq邮箱,比如说网易邮箱大师等。这说明邮件服务商提供了邮件服务器,但是用户代理却不局限与该厂商,而用户代理是通过邮件传输协议与邮件服务器进行通信的,也就是说我们只要理解了邮件传输协议,了解一门网络编程语言,就可以动手实现我们自己的邮件客户端了。
那么我们开始实现吧;
2. SMTP协议
SMTP的全称是Simple Mail Transfer Protocol,简单邮件传输协议。顾名思义,这个协议十分的简单,通过对该协议的RFC文档的阅读,我们可以掌握该协议的基本内容,了解从用户代理与邮件服务器的通信规则。
3 准备工作
- 阅读SMTP协议的RFC文档
- 搭Maven环境
- 编写代码
4. SMTP协议精要
RFC文档当然是英文的,本来非常害怕,但是发现他的内容其实很少,所以边看文档边查词典读了两遍(千万别怕),下面是主要内容介绍。
SMTP协议分为标准SMTP协议和扩展SMTP协议,标准SMTP协议是1982年在RFC821 文档中定义的,而扩展SMTP协议是1995年在RFC1869 文档中定义的。扩展SMTP协议在标准 SMTP协议基础上的改动非常小,主要增加了邮件安全方面的认证功能,现在我们说的SMTP协议基本上都是扩展SMTP协议。
introduction介绍:
主要介绍了SMTP扩展协议为消息传输代理提供了一个稳定的高效的基础(也就是说SMTP协议可以用来实现消息传输代理客户端,也急速邮件客户端)。然后说明了扩展的内容。
SMTP扩展协议的框架
SMTP传输的是邮件对象,邮件对象包括封面和内容
- 封面包括发件人的地址,多个收件人的地址和交付模式,使用一系列的协议单元发送。
- 内容包括头部和主题两个部分,使用SMTP数据协议单元发送,头部包括一系列键值对,头部总是使用ASCII编码
SMTP协议包含得多指令,但是只需要用到以下指令就可以完成简单的邮件发送
ehlo <domain>
如 ehlo zeng
与SMTP协议建立连接后需要发送的第一条命令。
auth para
设置验证方式,如
auth login
mail from: <发送者邮箱>
设置发送者邮箱,如
mail from:<xxxx@qq.com>
rcpt to:<收件者邮箱>
设置收件者邮箱,如
rcpt to:<xxxx@qq.com>
data
表示将要发送邮件的内容,这个命令后面的发送都是邮件内容
quit
结束邮件发送
所有命令末尾都是回车换行
5. 源码
import com.sun.xml.internal.messaging.saaj.util.Base64;
import lombok.Data;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/**
* @author zeng
*/
public class MyEmailClient {
public static void main(String[] args) throws IOException {
//敏感信息。。
Token token=new Token("",25,"","");
Socket socket=null;
PrintWriter printWriter=null;
BufferedReader br=null;
try {
//1. 连接smtp邮箱服务器
socket=new Socket(token.getAddress(),token.getPort());
printWriter=new PrintWriter(socket.getOutputStream(),true);
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
//2. 第一条命令 ehlo
printWriter.println("ehlo zeng");
System.out.println(br.readLine());
//3. 发送,auth
printWriter.println("auth login");
System.out.println(br.readLine());
//4. 用户名和密码
printWriter.println(token.getUserName());
printWriter.println(token.getPassWord());
//会有一大串信息返回,如果最后返回235 Authentication successful则成功
String temp=null;
while ((temp=br.readLine())!=null){
System.out.println(temp);
if ("235 Authentication successful".equals(temp)){
break;
}
}
System.out.println("认证成功");
//设置发件人和收件人,敏感信息
String sentUser="";
String recUser="";
printWriter.println("mail from:<"+sentUser+">");
System.out.println(br.readLine());
printWriter.println("rcpt to:<"+recUser+">");
System.out.println(br.readLine());
//设置data
printWriter.println("data");
System.out.println(br.readLine());
//设置邮件主题
printWriter.println("subject:test");
printWriter.println("from:"+sentUser);
printWriter.println("to:"+recUser);
//设置邮件格式
printWriter.println("Content-Type: text/plain;charset=\"utf8\"");
printWriter.println();
//邮件正文
printWriter.println("来自java手写smtp邮件客户端");
printWriter.println(".");
printWriter.print("");
System.out.println(br.readLine());
//退出
printWriter.println("rset");
System.out.println(br.readLine());
printWriter.println("quit");
System.out.println(br.readLine());
} catch (IOException e) {
e.printStackTrace();
}finally {
//释放连接
socket.close();
printWriter.close();
br.close();
}
}
}
@Data
class Token{
String address;
Integer port;
String userName;
String passWord;
Token(String address, Integer port, String userName, String passWord) {
this.address = address;
this.port = port;
this.userName = new String(Base64.encode(userName.getBytes()));
this.passWord = new String(Base64.encode(passWord.getBytes()));
}
}
6.题外话
之所以写这个的原因是自己把计网考完后阅读了《计算机网络 自顶向下方法》这本书,该书应用层协议的课后习题就有一个实现邮件客户端,当时看到这个题目的时候,感觉不可思议,因为之前课堂上学计网的时候都是一些理论的知识,真没想过自己动手写代码。之前在写Spring代码的时候也用过mail相关的类,所以自己也决定通过读RFC文档去实现一个自己的邮件客户端,以帮助我发现更多的乐趣。
使用java语言基于SMTP协议手写邮件客户端的更多相关文章
- 基于MATLAB的手写公式识别(9)
基于MATLAB的手写公式识别(9) 1.2图像的二值化 close all; clear all; Img=imread('drink.jpg'); %灰度化 Img_Gray=rgb2gray(I ...
- 基于MATLAB的手写公式识别(6)
基于MATLAB的手写公式识别 2021-03-29 10:24:51 走通了程序,可以识别"心脑血管这几个字",还有很多不懂的地方. 2021-03-29 12:20:01 tw ...
- 基于MATLAB的手写公式识别(5)
基于MATLAB的手写公式识别 总结一下昨天一天的工作成果: 获得了大致的识别过程. 一个图像从生肉到可以被处理需要经过预处理(灰质化.增加对比度.中值过滤.膨胀或腐蚀.闭环运算). 掌握了相关函数的 ...
- 基于MATLAB的手写公式识别(3)
基于MATLAB的手写公式识别 图像的膨胀化,获取边缘(思考是否需要做这种处理,初始参考样本相对简单) %膨胀 imdilate(dilate=膨胀/扩大) clc clear A1=imread(' ...
- 基于MATLAB的手写公式识别(2)
基于MATLAB的手写公式识别 图像的预处理(除去噪声.得到后续定位分割所需的信息.) 预处理其本质就是去除不需要的噪声信息,得到后续定位分割所需要的图像信息.图像信息在采集的过程中由于天气环境的影响 ...
- 基于MATLAB的手写公式识别(1)
基于MATLAB的手写公式识别 reason:课程要求以及对MATLAB强大生命力的探索欲望: plan date:2021/3/28-2021/4/12 plan: 进行材料搜集和思路整理: 在已知 ...
- python开发基于SMTP协议的邮件代发服务
写在这篇文章前照例给大家灌输点名词解释,理论知识,当然已经很熟悉的同学可以往下翻直接看干货 1. 什么是SMTP SMTP即简单传输协议(Simple Mail Transfer Protocol), ...
- Java:基于TCP协议网络socket编程(实现C/S通信)
目录 一.前言:TCP原理简介 二.Socket编程通信 三.TCP服务器端(具体代码) 四.TCP客户端(具体代码) 五.通信效果演示 六."创意"机器人:价值一个亿的AI核心代 ...
- 基于SMTP协议的CMD命令邮件发送
网上有不少的这类的文章,以是参照这些文章后,自己实际运行的结果.系统使用的是WIN7 旗舰版. 1.打开CMD命令后,连接到SMTP服务器,如连接到QQ的SMTP服务,输入命令 telnet smtp ...
随机推荐
- Android零基础入门第89节:Fragment回退栈及弹出方法
在上一期分享的文章末尾留了一个课后作业,有去思考如何解决吗?如果已经会了那么恭喜你,如果还不会也没关系,本期一起来学习. 一.回退栈 在前面两期的示例中,当我们完成一些操作后,如果想要回到操作之前的状 ...
- windows 2003 无法安装 .net4.0 windows服务
错误: InstallUtil.InstallLog文件中的错误信息: 正在运行事务处理安装. 正在开始安装的“安装”阶段. 查看日志文件的内容以获得 D:\Debug\DataChang.e ...
- FMX中实现PostMessage的方法
首先,做为一个从Windows下转过来的开发人员,许多时候,我们喜欢用PostMessage来触发一些异步执行的代码,但遗憾的是,FMX做为EMB的跨平台库的基础,只提供了SendMessage方法, ...
- Spring Framework 组件注册 之 @Import
Spring Framework 组件注册 之 @Import 写在前面 向spring中注册组件或者叫javaBean是使用spring的功能的前提条件.而且spring也提供了很多种方式,让我们可 ...
- 系统学习 Java IO (三)----文件类 File
目录:系统学习 Java IO---- 目录,概览 Java IO API 中的 File 类可以访问基础文件系统. 使用 File 类,可以: 检查文件或目录是否存在. 如果目录不存在,创建一个目录 ...
- idea初见问题整理_错误: -source 1.5 中不支持 diamond 运算符
最近在移动工程到idea下,顺便改目录结构,遇到的问题不一定全部记录,有些答案摘抄自别人博客,已注明来源,由于不是摘抄自同一作者,且有自己的一些内容,所以标注为原创. 1.(错误: -source 1 ...
- 21 | 移动测试神器:带你玩转Appium
- centos crontab用法详解 定时任务的设置
crontab 是用来让使用者在固定时间或固定间隔执行程序之用,类似于windows的计划任务 安装: yum -y install vixie-cron yum -y install crontab ...
- Fiddler如何过滤无用的链接
场景:现在是移动端的天下,测试过程中,抓包工具肯定必不可少,如何使用这里就不赘述,这里给大家讲述下如何过滤那些没有的链接,js ,png等无用的信息 工具:fiddler-use Filters功能: ...
- yarn or npm 版本固化如何选择
前言 作为前端开发者,npm这个包管理工具的重要性显而易见.优点不再表述,但一些缺点是为使用者诟病比较多的:速度慢.版本控制.下面主要讨论下npm的版本固化问题,即lock文件. npm语义化版本管理 ...