目录

一、前言:QQ邮件发送程序

二、封装SMTP操作

三、实现多线程接收

四、QQ邮件客户端界面设计

1、连接按钮

2、发送按钮

五、QQ邮件发送效果演示

六、总结


一、前言:QQ邮件发送程序

在上一篇《Java网络编程:实现QQ邮件发送客户端》,我们解决了telnet终端发送邮件误操作带来的麻烦,实现了自己的简单Java界面进行发送QQ邮件,界面可直接与smtp.qq.com服务器端建立连接,通过命令方式发送邮件信息。

这一篇为QQ邮件发送客户端程序设计的下篇,将实现更加完善的功能,不用命令发送方式,类似日常发送邮件,直接编写邮件标题、内容,然后直接发送即可,基本实现了QQ邮件发送客户端的功能,操作更加简便,实现自己的QQ邮件发送端,以后就用这个啦。

二、封装SMTP操作

原来的终端发送逐步操作如下:

HELO hostname   //回车,hostname可以是IP或其他随意别名
AUTH LOGIN //回车后,先粘贴base64程序编码的完整邮箱名并回车;再粘贴base64编码的授权码并回车 MAIL FROM:<czh_charzeus@qq.com> //在这里填写自己的邮箱地址,用于发送邮件(注意冒号后面别有空格)
RCPT TO:<czh_charzeus@qq.com> //接收方的邮箱,在这里暂时填写和上面一样的邮箱地址,即自己发送邮件给自己,验证是否成功
DATA //回车,接下来开始发送邮件头相关内容
Subject: the simple mail // 邮件的标题,回车
//在这里再多发送一行空行,来分隔邮件内容,下面就是邮件正文内容
Hello,the mail content!
测试发送邮件! //控制台中中文会变成?的乱码,但不影响接受者接收到中文内容
. //在邮件正文发送完毕后,单独用一行输入一个小圆点,作为结束标志,然后回车
QUIT //结束通信(含4次握手断开)

因此,我们要避免这种繁琐的命令形式,只需要将每个语句封装到发送程序里面,在用户界面则无需进行命令的输入,只需要输入内容。

实现的方法很简单,只需要在发送按钮中,把命令加进去就可以,如下:

tcpMailClient.send("HELO friend");
tcpMailClient.send("auth login"); String userNameBase64= encode(senderMail);
tcpMailClient.send(userNameBase64);
String authCode = encode("你的授权码");
tcpMailClient.send(authCode);
String msg = "mail from:<"+senderMail+">";
tcpMailClient.send(msg); msg = "rcpt to:<"+receiverMail+">";
tcpMailClient.send(msg); tcpMailClient.send("data"); msg="from:"+senderMail;
tcpMailClient.send(msg); msg="to:"+receiverMail;
tcpMailClient.send(msg); msg="subject:"+sub;
tcpMailClient.send(msg); tcpMailClient.send("\n");
// tcpMailClient.send("这是一封测试java客户端自动发送功能的邮件。");
tcpMailClient.send(content); tcpMailClient.send("."); tcpMailClient.send("quit");

从代码可以看到,当发送按钮一点击后,程序会执行所有语句,我们从上一篇知道,邮件服务器也会返回信息,所以QQ客户端需要使用多线程的技术,来处理返回信息,避免单线程阻塞导致发送不成功。

三、实现多线程接收

根据前面分析,将客户端接收的功能交给一个线程处理,就能够达到目的,不会因为接收语句阻塞使得主进程卡住。

所以,将线程放到连接按钮里面为好,在成功连接服务器之后,程序就启动线程,时机正好。连接按钮中的线程代码如下:

//用于接收服务器信息的单独线程
readThread = new Thread(()->{
String receiveMsg=null;//从服务器接收一串字符
while ((receiveMsg=tcpMailClient.receive())!=null){
String msgTemp = receiveMsg;
Platform.runLater(()->{
taDisplay.appendText(msgTemp+"\n");
});
}
Platform.runLater(()->{
taDisplay.appendText("对话已关闭!\n");
});
}); readThread.start();

程序执行发送每一条命令语句的速度比我们自己输入发送要快许多,为了避免QQ邮件接收服务器无法及时响应出错,程序自动发送过程中需要设置一定的睡眠等待时间,在send方法设置等待200ms或者500ms。

QQ邮件客户端实现代码可见上一篇Java网络编程:实现QQ邮件发送客户端,这里不再重复介绍。

public void send(String msg){
//输出字符流,由socket调用系统底层函数,经网卡发送字节流
pw.println(msg);
try {
//进行邮件交互,发送smtp指令之间应该暂停一段时间
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

四、QQ邮件客户端界面设计

界面的设计与以往类似,可以根据自己的需求设计不同的界面风格,可参考本文前言或者总结部分的系列文章进行实现。这里给出关键按钮的完整代码。

1、连接按钮

//连接按钮
btConn.setOnAction(event -> {
String ip=ipAddress.getText().trim();
String port=tfport.getText().trim();
try { tcpMailClient = new TCPMailClient(ip, port); //成功连接服务器,接受服务器发来的第一条欢迎信息
String firstMsg=tcpMailClient.receive();
taDisplay.appendText(firstMsg+"\n");
//用于接收服务器信息的单独线程
readThread = new Thread(()->{
String receiveMsg=null;//从服务器接收一串字符
while ((receiveMsg=tcpMailClient.receive())!=null){
//lambda表达式不能直接访问外部非final类型局部变量,需要定义一个临时变量
//若将receiveMsg定义为类成员变量,则无需临时变量
String msgTemp = receiveMsg;
Platform.runLater(()->{
taDisplay.appendText(msgTemp+"\n");
});
}
Platform.runLater(()->{
taDisplay.appendText("对话已关闭!\n");
});
}); readThread.start();
} catch (IOException e) {
e.printStackTrace();
} });

2、发送按钮

//发送按钮
btnSend.setOnAction(event -> {
String senderMail = mail.getText().trim();
String receiverMail = toMail.getText().trim();
String sub = subject.getText();
String content = tfSend.getText();
try { tcpMailClient.send("HELO friend");
tcpMailClient.send("auth login"); String userNameBase64= encode(senderMail);
tcpMailClient.send(userNameBase64);
String authCode = encode("你的授权码");
tcpMailClient.send(authCode);
String msg = "mail from:<"+senderMail+">";
tcpMailClient.send(msg); msg = "rcpt to:<"+receiverMail+">";
tcpMailClient.send(msg); tcpMailClient.send("data"); msg="from:"+senderMail;
tcpMailClient.send(msg); msg="to:"+receiverMail;
tcpMailClient.send(msg); msg="subject:"+sub;
tcpMailClient.send(msg); tcpMailClient.send("\n");
// tcpMailClient.send("这是一封测试java客户端自动发送功能的邮件。");
tcpMailClient.send(content); tcpMailClient.send("."); tcpMailClient.send("quit"); }catch (Exception e){
taDisplay.appendText("服务器连接失败!"+e.getMessage()+"\n");
}
});

QQ客户端的程序可以沿用之前的内容,详见这篇:基于TCP协议网络socket编程(java实现C/S通信)

五、QQ邮件发送效果演示

细心的读者可以发现,在我点击发送之后,程序卡断了一会,其实就是因为我设置发送睡眠1000ms,实际可以发送成功,建议设置200ms或以上!

发送到自己QQ邮箱:

发送到自己的126邮箱进行测试:

六、总结

这一篇为QQ邮件发送客户端程序设计的下篇,记录了实现的关键部分,不用命令发送方式,类似日常发送邮件,直接编写邮件标题、内容,然后直接发送即可,基本实现了QQ邮件发送客户端的功能,操作更加简便。根据本篇的知识内容,后面可以实现更加完善的QQ邮件发送小程序,增加一系列小功能!

如果觉得不错欢迎“一键三连”哦,点赞收藏关注,有问题直接评论,交流学习!


我的博客园:https://www.cnblogs.com/chenzhenhong/p/14331829.html

我的CSDN博客:https://blog.csdn.net/Charzous/article/details/111148425

版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。

Java实现QQ邮件发送客户端的更多相关文章

  1. Java网络编程:QQ邮件发送客户端程序设计

    目录 一.目标介绍 1.认识SMTP(邮件传输协议) 2.POP3(邮件接收协议) 二.基于Base64编码邮箱及授权码 1.开通QQ邮箱SMTP/POP3服务 2.Java编写BASE64编码程序 ...

  2. Java实现QQ邮件发送

    首先我们需要两个jar包,点击下面即可下载这两个包: JavaMail mail.jar 1.4.5 JAF(版本 1.1.1) activation.jar 我们这里采用QQ邮箱发送邮件为例,代码如 ...

  3. JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架)

    JAVA 实现 QQ 邮箱发送验证码功能(不局限于框架) 本来想实现 QQ 登录,有域名一直没用过,还得备案,好麻烦,只能过几天再更新啦. 先把实现的发送邮箱验证码更能更新了. 老规矩,更多内容在注释 ...

  4. Spring进阶—如何用Java代码实现邮件发送(一)

    相关文章: <Spring进阶—如何用Java代码实现邮件发送(二)> 在一些项目里面如进销存系统,对一些库存不足发出预警提示消息,招聘网站注册用户验证email地址等都需要用到邮件发送技 ...

  5. 线程——QQ邮件发送

    一.造一个QQ邮件发送的窗体 二.开始编写关于邮件发送的代码,以及当点发送按钮的时候,给发送按钮单独造了一个新的线程.这样如果发送的附件太多的话,如果不给发送按钮造新的线程,便会卡住,但是如果给发送按 ...

  6. java实现smtp邮件发送

    一.准备工作 首先你需要已一个发送邮箱,一般的邮箱都有SMTP.POP3服务,比如QQ邮箱,登陆QQ邮箱开启SMTP服务,开启是服务器会提示你设置独立密码,这个密码是跟邮箱正常登陆的密码不同的,这个是 ...

  7. Java实现多线程邮件发送

    利用java多线程技术配合线程池实现多任务邮件发送. 1.基本邮件发送MailSender package hk.buttonwood.ops.email; import java.io.File; ...

  8. java简单的邮件发送

    java实现简单的邮件发送案例,学会了这个你就可以利用这个来整你的好友了,不断地给他进行邮箱轰炸(当然个人不建议瞎搞),最重要的是明白其中的原理最好了.话不多说,直接看代码案例了.首先需要导入的jar ...

  9. python定时利用QQ邮件发送天气预报

    大致介绍 好久没有写博客了,正好今天有时间把前几天写的利用python定时发送QQ邮件记录一下 1.首先利用request库去请求数据,天气预报使用的是和风天气的API(www.heweather.c ...

随机推荐

  1. Appium App UI 自动化测试理论知识

    (一)App自动化测试背景 随着移动终端的普及,手机应用越来越多,也越来越重要.App的回归测试用例数量越来越多,全量回归也越来越消耗时间.另外移动端碎片化严重(碎片化:兼容性测试,手机品牌多样.An ...

  2. Autofac官方文档翻译--一、注册组件--3属性和方法注入

    官方文档:http://docs.autofac.org/en/latest/register/prop-method-injection.html Autofac 属性和方法注入 虽然构造函数参数注 ...

  3. nodejs+express+mongodb 快速接口开发

    nodejs+mongodb+express API快速生成 使用说明 安装 $ npm install duzq-quick-mongo 建立mongodb数据模型 const mongoose = ...

  4. 怎么同步fork原git项目

    如何实现 有时候,我们看到有价值的git项目,通常,我们会选择把原项目fork过来,然后自己去把玩研究.然而,原项目进行了更新,fork过来的代码却还是原来的版本,那有没有什么做法,能同时更新到我自己 ...

  5. 10分钟带你入门git到github

    git的产生背景 开局先来一个故事吧,故事看完如果不想看枯燥无味的指令,没关系我已经把这篇文章的内容录制成了一个视频,点击文末阅读原文就可以观看.或者说你已经熟练掌握git的使用了,可以直接跳到总结部 ...

  6. Idea创建Maven项目时,没有自动添加Artifacts

    可能的原因是没有进行更新,因为第一次创建时由于要下载东西,所以pom文件是自动改变的,如果没有设置自动更新maven项目,就可能出现这种情况 这时候只要去maven project中点击一下更新按钮, ...

  7. JavaSwing 船只停靠管理可视化(二)

    JavaSwing 船只停靠管理可视化(一) JavaSwing 船只停靠管理可视化(二) JavaSwing 船只停靠管理可视化(三) JavaSwing 船只停靠管理可视化(四) JavaSwin ...

  8. JAVA NIO Selector Channel

    These four events are represented by the four SelectionKey constants: SelectionKey.OP_CONNECT Select ...

  9. vuetify 属性集合

    1.v-form 组件具有 three 功能,可以通过在该组件上设置 ref 来访问它们. ref 允许我们访问组件上的内部方法,例如 <v-form ref="form"& ...

  10. 学生成绩管理系统: 统计成绩排序并打印(c++)(内含读取文件.txt及将文件输出excel的方法)

    实验要求:输入30个学生的学号.姓名和5门课程的成绩,计算总分并按照总分排出名次,最后按照学号顺序打印成绩单, 并把成绩单输出为excel文件. txt数据: 2015020981 甲 90 89 9 ...