使用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. 第一条命令 ehloprintWriter.println("ehlo zeng");System.out.println(br.readLine());//3. 发送,authprintWriter.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());//设置dataprintWriter.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文档去实现一个自己的邮件客户端,以帮助我发现更多的乐趣。
转载于:https://www.cnblogs.com/zeng-xian-hui/p/11221519.html
使用java语言基于SMTP协议手写邮件客户端相关推荐
- linux下基于SMTP协议的C++邮件客户端
完整代码下载: https://github.com/WaPonX/SMTPMail 在网络中使用SMTP登陆的时候,需要将代码转换成base64编码. 下面这个函数是从网上抄的: #include ...
- Java中使用SMTP协议发送电子邮件
Java中使用SMTP协议发送电子邮件的具体的步骤: 1.首先需要获取发送邮件的Session对象 Session session = Session.getDefaultInstance(prope ...
- 基于SMTP协议的电子邮件客户端程序
基于SMTP协议的电子邮件客户端程序 电子邮件的完整传输过程: 发件人 -> MUA -> MTA -> MTA -> 若干个MTA -> MDA <- MUA ...
- 基于CNN的手写数字识别
基于CNN的手写数字识别 文章目录 基于CNN的手写数字识别 零. 写在之前 壹. 聊聊CNN 01. 什么是CNN 02. 为什么要有CNN 03. CNN模型 3.1 卷积层 3.2 池化层 3. ...
- 基于SMTP协议的模拟邮件系统(计算机网络课程设计)
目录 一.设计内容 二.所用到的知识 三.需求分析 四.运行效果 1.登录与注册 2.信息管理 3.邮件发送与收取 五.部分核心代码 1.SendServlet.java(实现邮件发送) 2.Rece ...
- DL之RBM:基于RBM实现手写数字图片识别提高准确率
DL之RBM:基于RBM实现手写数字图片识别提高准确率 目录 输出结果 设计代码 输出结果 设计代码 import numpy as np import matplotlib.pyplot as pl ...
- TF之LiR:基于tensorflow实现手写数字图片识别准确率
TF之LiR:基于tensorflow实现手写数字图片识别准确率 目录 输出结果 代码设计 输出结果 Extracting MNIST_data\train-images-idx3-ubyte.gz ...
- 我的Go+语言初体验——Go+语言构建神经网络实战手写数字识别
"我的Go+语言初体验" | 征文活动进行中- 我的Go+语言初体验--Go+语言构建神经网络实战手写数字识别 0. 前言 1. 神经网络相关概念 2. 构建神经网络实战手写数字识 ...
- 基于tensorflow的手写数字识别
基于tensorflow的手写数字识别 数据准备 引入包 加载数据 查看数据信息 查看一张图片 数据预处理 搭建网络模型 模型的预测与评价 模型的展示 对一张图片进行预测 准确率 数据准备 引入包 i ...
最新文章
- java程序a-z b-y_有一行电文,以按下面规律译成密码: A---Z a---z B---Y b---Y C---X c---x …… 即第1个字母编程第26个字...
- 好久没来了,发个招聘贴
- VSS2005 添加文件夹方法!
- wordpress 后台页面无法显示绑定的台湾语言
- vue父子组件生命周期顺序_vue父子组件生命周期执行顺序
- python内置对象是什么_Python内置对象类型之数字类型
- 工作流性能优化(敢问activiti有扩展性?)(3)
- [UE4] Component BluePrint 组合 代替 BluePrint 继承 实现 ECS 结构
- Go Web编程--使用bcrpyt哈希用户密码
- gba徽章机器人_《徽章机器人》倒计时网站开启 20周年纪念插画欣赏
- MOM SMS SharePoint
- Kaldi语料的两种切分/组织方式及其处理
- 『提醒自己』-自身遗忘掉的知识1
- 获取阿里云播放器当前播放速率
- HLOJ486 种花小游戏
- kubernetes更换IP地址重新初始化master节点
- 负载均衡(Load Balance)介绍
- 如何用matlab画超越方程组的图像,【求助】超越方程组的fsolve解法
- css鼠标经过字体抖动,jQuery+css3实现文字跟随鼠标的上下抖动
- LED显示屏测试软件 v2.0
热门文章
- oracle中ccuser,Oracle数据库查询与SESSIONS_PER_USER大于40
- 看现在的影视电视剧植入广告和软件模式
- 带有ANY(SOME)或ALL谓词子查询
- Algorithm——高楼扔鸡蛋
- FullCalendar(日程管理控件)
- Linux上检测sendmail,linux下sendmail的安装与配置
- 职场人的路子该怎么走?有一种折腾叫无悔
- NP理论(2):“判定问题”与“停机问题” 精选
- win7计算机用户设置口令,几步教会你win7共享打印机设置密码_打印机怎么设置用户密码...
- 数据结构基础之动态数组