Qt编写的SMTP客户端(库)

允许应用程序通过SMTP发送电子邮件(有文本,html,附件,内联文件等的MIME)。并支持SSL和SMTP身份验证。

Qt SMPT客户端支持

(1) 与SMTP服务器的TCP和SSL连接。
(2) SMTP验证(PLAIN和LOGIN方法)。
(3) 发送MIME电子邮件(给多个收件人)。
(4) 电子邮件中的纯文本和HTML(带有内联文件)内容。
(5) 多个附件和内联文件(用于HTML)。
(6) 不同的字符集(ascii,utf-8等)和编码方法(7位,8位,base64)。
(7) 错误处理。

示例1 -一封简单的(纯文本)电子邮件

#include <QtGui/QApplication>
#include "../src/SmtpMime"int main(int argc, char *argv[])
{QApplication a(argc, argv);// 这是Qt项目的Smtpclient的第一个演示应用程序// 首先,我们需要创建一个Smtpclient对象// 我们将使用Gmail的smtp服务器(smtp.gmail.com,端口465,ssl)SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);// 我们需要设置用户名(您的电子邮件地址)和密码// 为smtp认证。smtp.setUser("your_email_address@gmail.com");smtp.setPassword("your_password");// 现在我们创建一个MimeMessage对象。这是邮件。MimeMessage message;    message.setSender(EmailAddress("your_email_address@gmail.com", "Your Name"));message.addRecipient(EmailAddress("recipient@host.com", "Recipient's Name"));message.setSubject("SmtpClient for Qt - Demo");// 现在向电子邮件中添加一些文本。// 首先,我们创建一个Mimetext对象。MimeText text;text.setText("Hi,\nThis is a simple email message.\n");// 现在将其添加到邮件中message.addPart(&text);// 现在我们可以寄信了smtp.connectToHost();smtp.login();smtp.sendMail(message);smtp.quit();}

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓

示例2 -发送附件

#include <QtGui/QApplication>
#include "../src/SmtpMime"int main(int argc, char *argv[])
{QApplication a(argc, argv);// 首先创建Smtpclient对象并设置用户和密码。SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);smtp.setUser("your_email_address@gmail.com");smtp.setPassword("your_password");// 创建一个 MimeMessageMimeMessage message;message.setSender(EmailAddress("your_email_address@gmail.com", "Your Name"));message.addRecipient(EmailAddress("recipient@host.com", "Recipient's Name"));message.setSubject("SmtpClient for Qt - Demo");// 添加一些文本MimeText text;text.setText("Hi!\n This is an email with some attachments.");message.addPart(&text);// 现在我们创建附件对象QFile image("image1.jpg");MimeAttachment attachment(&image);// 可以设置文件类型。(默认是application/octet-stream)attachment.setContentType("image/jpg");// 现在将其添加到消息中message.addPart(&attachment);// 添加另一个附件QFile document("document.pdf")MimeAttachment documentAttachment(&document);message.addPart(&documentAttachment);// 现在我们可以寄信了smtp.connectToHost();smtp.login();smtp.sendMail(message);smtp.quit();}

示例3 -带有嵌入图像的HTML电子邮件(内联文件)

#include <QtGui/QApplication>
#include "../src/SmtpMime"int main(int argc, char *argv[])
{QApplication a(argc, argv);// 首先创建Smtpclient对象并设置用户和密码。SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);smtp.setUser("your_email@gmail.com");smtp.setPassword("your_password");// 创建一个 MimeMessageMimeMessage message;message.setSender(EmailAddress("your_email_address@gmail.com", "Your Name"));message.addRecipient(EmailAddress("recipient@host.com", "Recipient's Name"));message.setSubject("SmtpClient for Qt - Example 3 - Html email with images");// 现在我们需要为HTML内容创建一个MimeHtml对象。MimeHtml html;html.setHtml("<h1> Hello! </h1>""<h2> This is the first image </h2>""<img src='cid:image1' />""<h2> This is the second image </h2>""<img src='cid:image2' />");// 为每个图像创建一个MimeInlineFile对象QFile imageFile1("image1.jpg");MimeInlineFile image1 (&imageFile1);// 必须设置唯一的内容idimage1.setContentId("image1");image1.setContentType("image/jpg");QFile imageFile2("image2.jpg");MimeInlineFile image2 (&imageFile2);image2.setContentId("image2");image2.setContentType("image/jpg");message.addPart(&html);message.addPart(&image1);message.addPart(&image2);// 现在可以发送邮件了smtp.connectToHost();smtp.login();smtp.sendMail(message);smtp.quit();
}

使用方法:

1. 我这里下载的版本是SmtpClient-for-Qt v2.0的,首先使用Qt打开SMTPEmail.pro文件,编译出SmtpMime2.dll动态库,编译动态库的原因是因为里面的demo运行时需要链接这个动态库。我编的是debug版的,你也可以编release的不过要放到对应的文件夹下。

如下图所示:

2. 再把步骤1中生成的SmtpMime2.dll文件拷贝到对应的debug或release目录下,我这里使用是debug的所以拷到debug文件下。

如下图所示:

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓

3. 双击打开demo2.pro文件,修改成SmtpMime2.dll库的路径即可。注意 : 路径一定要对否则编译会报错

如下图所示:

4.最后编译+运行,就可以成功地把demo2跑起来了,其他demo的使用方法应该也类似。

如下图所示:

5. 当你点击发送邮件的时候可能会报错以下错误: qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed ,这个时候需要安装OpenSSL。

6. 安装OpenSSL

6.1 背景
Qt 使用QNetwork 模块,进行api请求时发生错误,错误信息:qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

6.2 原因
当你用HTTP形式的时候,会发现没有问题,而使用HTTPS时,则会报错。如果对计算机网络有所了解的人,应该大致懂原因。因为HTTP 是超文本传输协议,信息是明文传输,存在安全风险的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。

SSL/TLS 协议建立的详细流程:

Client
首先,由客户端向服务器发起加密通信请求,也就是 Client的请求。在这一步,客户端主要向服务器发送以下信息:
(1)客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本。
(2)客户端生产的随机数( Client Random ),后面用于生产「会话秘钥」。
(3)客户端支持的密码套件列表,如 RSA 加密算法。

Sever
服务器收到客户端请求后,向客户端发出响应 。服务器回应的内容有如下内容:
(1)确认 SSL/ TLS 协议版本,如果浏览器不支持,则关闭加密通信。
(2)服务器生产的随机数( Server Random ),后面用于生产「会话秘钥」。
(3)确认的密码套件列表,如 RSA 加密算法。
(4)服务器的数字证书。

客户端回应
客户端收到服务器的回应之后,首先通过浏览器或者操作系统中的 CA 公钥,确认服务器的数字证书的真实性。如果证书没有问题,客户端会从数字证书中取出服务器的公钥,然后使用它加密报文,向服务器发送如下信息:
(1)一个随机数( pre-master key )。该随机数会被服务器公钥加密。
(2)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
(3)客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供服务端校验。
上面第一项的随机数是整个握手阶段的第三个随机数,这样服务器和客户端就同时有三个随机数,接着就用双方协商的加密算法,各自生成本次通信的「会话秘钥」。

服务器的最后回应
服务器收到客户端的第三个随机数( pre-master key )之后,通过协商的加密算法,计算出本次通信的「会话秘钥」。然后,向客户端发生最后的信息:
(1)加密通信算法改变通知,表示随后的信息都将用「会话秘钥」加密通信。
(2)服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时把之前所有内容的发生的数据做个摘要,用来供客户端校验。
至此,整个 SSL/TLS 的握手阶段全部结束。接下来,客户端与服务器进入加密通信,就完全是使用普通的 HTTP 协议,只不过用「会话秘钥」加密内容。
回到qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed,那么这个报错,就是缺少加密的手段,也就是没有提供对HTTP加密的工具,从而无法进行HTTPS通信。

6.3 解决方案
那么原因清楚了,就应该知道,我们需要把加密这一步缺少的东西给补上。先说一点,Qt本身是支持ssl的,但是因为法律原因?没有自带对应的dll。

我们先使用这段代码打印当前Qt支持的ssl版本:

#include <QSslSocket>
#include <QDebug>
qDebug()<< QSslSocket::sslLibraryBuildVersionString();

使用网络需要加上Qt的网络模块,在pro文件里加上:

QT += network

我这里输出的是

"OpenSSL 1.1.1d  10 Sep 2019"

6.4 接下来就去下载OpenSSL,下载方式有两种:

(1). 下载OpenSSL源码,自行编译
https://www.openssl.org/source/

(2). 直接下载dll
Openssl下载网站: http://slproweb.com/products/Win32OpenSSL.html
我推荐第二个方法,省去自己编译的时间。
然后在这个网站找到对应的版本,比如我的版本是刚刚打印的1.1.1,同时,也要注意工程是32位还是64位,我这里选择的是Win64 OpenSSL v1.1.1n Light,至于EXE还是MSI都没差异。

6.5 安装的时候,我选择的是第二个,这样可以方便的进行dll文件的拷贝。

6.6 进入OpenSSL安装目录。bin目录下,拷贝这两个dll文件到工程的exe程序所在路径下。

6.7 比如我这里的路径,直接放到exe根路径下即可,然后程序即可正常运行。

6.8 填写好正确的邮箱和密码再次点击发送邮件,如果说提示"Authentification Failed"或者提示"Mail sending failed"可能是你填写的邮箱和密码错了.

6.9 下面是邮件发送成功的截图:

qq邮箱收到的邮件:

这里我也测试了一下,不同OpenSSL 版本的dll是否可以通用,发现高低版本都不行,必须得和Qt 打印出来的OpenSSL 版本一致才行。

另外,很多帖子都是说,把这两个dll文件放到E:\QT\5.12.3\mingw73_64\bin路径下,即Qt的安装路径下。这样也可以,但是我觉得不好,个人认为,尽量别去动Qt安装路径下的文件,保证不会被认为破坏开发环境,或者以后排错,不会导致当时自己把文件放到了Qt安装路径下太久忘记,而在别的电脑上无法正常使用的情况。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓

Qt编写的SMTP客户端(库)相关推荐

  1. 使用QT编写TCP服务器与客户端程序

    建立工程 在学习了霍亚飞的<Qt Creator快速入门(第3版)>后,参考"18.4 TCP"中的示例程序,编写了一个在同一个工程中实现服务器与客户端的习作程序,变量 ...

  2. qt编写activex_Qt中使用ActiveX(一)

    由于最近需要使用ActiveX,一般来说可以使用微软提供的MFC或者ATL框架来开发,由于我个人对这部分内容不是很熟悉,好在Qt也提供对于ActiveX的支持.本文主要记录个人学习ActiveX的一些 ...

  3. Qt编写项目作品大全(自定义控件+输入法+大屏电子看板+视频监控+楼宇对讲+气体安全等)...

    一.自定义控件大全 (一).控件介绍 超过150个精美控件,涵盖了各种仪表盘.进度条.进度球.指南针.曲线图.标尺.温度计.导航条.导航栏,flatui.高亮按钮.滑动选择器.农历等.远超qwt集成的 ...

  4. Qt编写视频监控管理平台(支持海康/大华/宇视/华为/天地伟业/H264/H265等)

    一.前言 海康大华等厂家自己的客户端软件,基本上都是支持自家的设备,不支持其他家的摄像机和硬盘录像机,并不是因为技术上做不到,这些大厂要实现支持兼容其他的家的(他们家的服务端或者收费的都是支持其他家的 ...

  5. Qt编写控件属性设计器7-串口采集

    一.前言 数据源是组态软件的核心灵魂,少了数据源,组态就是个花架子没卵用,一般数据源有三种方式获取,串口.网络.数据库,至于数据规则是什么,这个用户自己指定,本设计器全部采用第一个字节作为数据来演示. ...

  6. 使用Qt编写模块化插件式应用程序

    动态链接库技术使软件工程师们兽血沸腾,它使得应用系统(程序)可以以二进制模块的形式灵活地组建起来.比起源码级别的模块化,二进制级别的模块划分使得各模块更加独立,各模块可以分别编译和链接,模块的升级不会 ...

  7. 功能强大的 C++ redis 客户端库增加至 acl 项目中

    虽然 redis 开发库已有不少,但 C/C++ 的客户端库好用的并不多,虽然官方也提供了 C 版的客户端库,但易用性较差,而且不支持连接池功能,相对于 C/C++ 的库,JAVA 版的 jedis ...

  8. golang 编写的邮件客户端

    近期开始学习 golang ,编写了邮件客户端: golang编写的邮件客户端[一]基本框架搭建:从smtp服务器获取消息 golang编写的邮件客户端[二]添加读写协程 转载于:https://ww ...

  9. 【Alljoyn】 Alljoyn学习笔记七 Alljoyn瘦客户端库介绍

    Alljoyn瘦客户端库介绍(上) 1.简介 本文档对AllJoynTM瘦客户端的核心库文件(AJTCL)进行了详尽的介绍.本文档介绍了系统整体架构,AllJoyn框架结构,并着重于介绍如何将嵌入式设 ...

  10. ROS2学习(七).ROS概念 - ROS客户端库(Ros Client Library)

    ROS客户端库 概述 支持的客户端库 通用功能:RCL 语言特有功能 同ROS 1的比较 小结 参考 概述 客户端库是开发者用以开发ROS代码时使用的API,使用客户端库,开发者将接触到ROS的相关概 ...

最新文章

  1. python使用xlrd模块读写excel
  2. 盛大游戏杯第十五届上海大学程序设计联赛暨上海金马五校赛
  3. layerconfirm 自动关闭问题 没有阻塞问题_微信新版本自动更新?赶紧关闭这个功能...
  4. 解决w3wp.exe内存占用问题[转载]
  5. NetDevOps网络设备日志分析与环境搭建-EFK(Elasticsearch+Filebeat+Kibana)
  6. jupyter notebook输出表格
  7. 搞懂激活函数(Sigmoid/ReLU/LeakyReLU/PReLU/ELU)
  8. C#语言对AutoCAD二次开发(二)
  9. 支持Kubernetes集群运维审计,JumpServer v2.2.0发布丨Release Notes
  10. 【转】安装虚拟机VMware及在VMware下安装Ghost XP系统图文教程(附PQ分区及VMwa
  11. 10年的工作经验?还是1个经验反复用了10年?
  12. matlab读ascii的dat,[转载]MATLAB读取和调用各种数据(txt,dat,ma
  13. ASP.NET Web程序设计 第三章 高级控件
  14. 中国工业钩环市场深度研究分析报告
  15. Maven Resources Compiler: Failed to copy ‘XXX‘ to ‘target/xxx‘编译报错
  16. ZigBee 3.0实战教程-Silicon Labs EFR32+EmberZnet-2-02:资源包详解
  17. 梅森数形如2 ​n ​​ −1的素数称为梅森数(Mersenne Number)。例如2 ​2 ​​ −1=3、2 ​3 ​​ −1=7都是梅森数。1722年,双目失明的瑞士数学大师欧拉证明了2 ​3
  18. 基于模板匹配的手写字体数字识别-含Matlab代码
  19. 各种第三方UI组件的引入(Vue)
  20. 全面剖析固态硬盘M.2接口与PCI-E SSD固态硬盘的关系

热门文章

  1. 安徽计算机在职研究生学校,安徽能读在职研究生有哪几个学校
  2. 局域网oracle 速度慢,[转帖]局域网中其他用户感觉上网速度慢、网速卡
  3. 文件夹中所有图片合成视频
  4. Movist Pro for Mac 2.2.16 — 播放器
  5. 测试人员日常基本工作流程
  6. 不在同一局域网?组建家庭局域网的方案和踩坑
  7. java swing企业人事管理系统 java swing mysql实现的企业人事管理系统源码和导入文档(1013)
  8. 常见服务器故障有哪些?如何预防服务器发生故障?服务器故障后如何恢复数据?
  9. python打字_Python编写打字训练小程序
  10. KGB知识图谱完善保险行业的知识应用体系