欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt實(shí)現(xiàn)編寫SMTP客戶端的示例詳解

 更新時間:2022年11月17日 08:53:13   作者:音視頻開發(fā)老舅  
這篇文章主要介紹了如何通過Qt實(shí)現(xiàn)編寫SMTP客戶端,可以實(shí)現(xiàn)通過SMTP發(fā)送電子郵件(有文本,html,附件,內(nèi)聯(lián)文件等的MIME)。并支持SSL和SMTP身份驗(yàn)證,感興趣的可以學(xué)習(xí)一下

Qt編寫的SMTP客戶端(庫)

允許應(yīng)用程序通過SMTP發(fā)送電子郵件(有文本,html,附件,內(nèi)聯(lián)文件等的MIME)。并支持SSL和SMTP身份驗(yàn)證。

Qt SMPT客戶端支持

(1) 與SMTP服務(wù)器的TCP和SSL連接。

(2) SMTP驗(yàn)證(PLAIN和LOGIN方法)。

(3) 發(fā)送MIME電子郵件(給多個收件人)。

(4) 電子郵件中的純文本和HTML(帶有內(nèi)聯(lián)文件)內(nèi)容。

(5) 多個附件和內(nèi)聯(lián)文件(用于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項(xiàng)目的Smtpclient的第一個演示應(yīng)用程序
 
    // 首先,我們需要創(chuàng)建一個Smtpclient對象
    // 我們將使用Gmail的smtp服務(wù)器(smtp.gmail.com,端口465,ssl)
 
    SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);
 
    // 我們需要設(shè)置用戶名(您的電子郵件地址)和密碼
    // 為smtp認(rèn)證。
 
    smtp.setUser("your_email_address@gmail.com");
    smtp.setPassword("your_password");
 
    // 現(xiàn)在我們創(chuàng)建一個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");
 
    // 現(xiàn)在向電子郵件中添加一些文本。
    // 首先,我們創(chuàng)建一個Mimetext對象。
 
    MimeText text;
 
    text.setText("Hi,\nThis is a simple email message.\n");
 
    // 現(xiàn)在將其添加到郵件中
 
    message.addPart(&text);
 
    // 現(xiàn)在我們可以寄信了
 
    smtp.connectToHost();
    smtp.login();
    smtp.sendMail(message);
    smtp.quit();
 
}

示例2 -發(fā)送附件

#include <QtGui/QApplication>
#include "../src/SmtpMime"
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
 
    // 首先創(chuàng)建Smtpclient對象并設(shè)置用戶和密碼。
    SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);
    smtp.setUser("your_email_address@gmail.com");
    smtp.setPassword("your_password");
 
    // 創(chuàng)建一個 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 text;
    text.setText("Hi!\n This is an email with some attachments.");
    message.addPart(&text);
 
    // 現(xiàn)在我們創(chuàng)建附件對象
    QFile image("image1.jpg");
    MimeAttachment attachment(&image);
 
    // 可以設(shè)置文件類型。(默認(rèn)是application/octet-stream)
    attachment.setContentType("image/jpg");
 
    // 現(xiàn)在將其添加到消息中
    message.addPart(&attachment);
 
    // 添加另一個附件
    QFile document("document.pdf")
    MimeAttachment documentAttachment(&document);
    message.addPart(&documentAttachment);
 
    // 現(xiàn)在我們可以寄信了
    smtp.connectToHost();
    smtp.login();
    smtp.sendMail(message);
    smtp.quit();
 
}

示例3 -帶有嵌入圖像的HTML電子郵件(內(nèi)聯(lián)文件)

#include <QtGui/QApplication>
#include "../src/SmtpMime"
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
 
    // 首先創(chuàng)建Smtpclient對象并設(shè)置用戶和密碼。
 
    SmtpClient smtp("smtp.gmail.com", 465, SmtpClient::SslConnection);
 
    smtp.setUser("your_email@gmail.com");
    smtp.setPassword("your_password");
 
    // 創(chuàng)建一個 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 - Example 3 - Html email with images");
 
 
    // 現(xiàn)在我們需要為HTML內(nèi)容創(chuàng)建一個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' />");
 
 
    // 為每個圖像創(chuàng)建一個MimeInlineFile對象
    QFile imageFile1("image1.jpg");
    MimeInlineFile image1 (&imageFile1);
 
    // 必須設(shè)置唯一的內(nèi)容id
    image1.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);
 
    // 現(xiàn)在可以發(fā)送郵件了
 
    smtp.connectToHost();
    smtp.login();
    smtp.sendMail(message);
    smtp.quit();
}

使用方法

1. 我這里下載的版本是SmtpClient-for-Qt v2.0的,首先使用Qt打開SMTPEmail.pro文件,編譯出SmtpMime2.dll動態(tài)庫,編譯動態(tài)庫的原因是因?yàn)槔锩娴膁emo運(yùn)行時需要鏈接這個動態(tài)庫。我編的是debug版的,你也可以編release的不過要放到對應(yīng)的文件夾下。

如下圖所示:

2. 再把步驟1中生成的SmtpMime2.dll文件拷貝到對應(yīng)的debug或release目錄下,我這里使用是debug的所以拷到debug文件下。

如下圖所示:

3. 雙擊打開demo2.pro文件,修改成SmtpMime2.dll庫的路徑即可。注意 : 路徑一定要對否則編譯會報(bào)錯

如下圖所示:

4.最后編譯+運(yùn)行,就可以成功地把demo2跑起來了,其他demo的使用方法應(yīng)該也類似。

如下圖所示:

5. 當(dāng)你點(diǎn)擊發(fā)送郵件的時候可能會報(bào)錯以下錯誤: qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed ,這個時候需要安裝OpenSSL。

6. 安裝OpenSSL

6.1 背景

Qt 使用QNetwork 模塊,進(jìn)行api請求時發(fā)生錯誤,錯誤信息:qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

6.2 原因

當(dāng)你用HTTP形式的時候,會發(fā)現(xiàn)沒有問題,而使用HTTPS時,則會報(bào)錯。如果對計(jì)算機(jī)網(wǎng)絡(luò)有所了解的人,應(yīng)該大致懂原因。因?yàn)镠TTP 是超文本傳輸協(xié)議,信息是明文傳輸,存在安全風(fēng)險的問題。HTTPS 則解決 HTTP 不安全的缺陷,在 TCP 和 HTTP 網(wǎng)絡(luò)層之間加入了 SSL/TLS 安全協(xié)議,使得報(bào)文能夠加密傳輸。

SSL/TLS 協(xié)議建立的詳細(xì)流程:

Client

首先,由客戶端向服務(wù)器發(fā)起加密通信請求,也就是 Client的請求。在這一步,客戶端主要向服務(wù)器發(fā)送以下信息:

(1)客戶端支持的 SSL/TLS 協(xié)議版本,如 TLS 1.2 版本。

(2)客戶端生產(chǎn)的隨機(jī)數(shù)( Client Random ),后面用于生產(chǎn)「會話秘鑰」。

(3)客戶端支持的密碼套件列表,如 RSA 加密算法。

Sever

服務(wù)器收到客戶端請求后,向客戶端發(fā)出響應(yīng) 。服務(wù)器回應(yīng)的內(nèi)容有如下內(nèi)容:

(1)確認(rèn) SSL/ TLS 協(xié)議版本,如果瀏覽器不支持,則關(guān)閉加密通信。

(2)服務(wù)器生產(chǎn)的隨機(jī)數(shù)( Server Random ),后面用于生產(chǎn)「會話秘鑰」。

(3)確認(rèn)的密碼套件列表,如 RSA 加密算法。

(4)服務(wù)器的數(shù)字證書。

客戶端回應(yīng)

客戶端收到服務(wù)器的回應(yīng)之后,首先通過瀏覽器或者操作系統(tǒng)中的 CA 公鑰,確認(rèn)服務(wù)器的數(shù)字證書的真實(shí)性。如果證書沒有問題,客戶端會從數(shù)字證書中取出服務(wù)器的公鑰,然后使用它加密報(bào)文,向服務(wù)器發(fā)送如下信息:

(1)一個隨機(jī)數(shù)( pre-master key )。該隨機(jī)數(shù)會被服務(wù)器公鑰加密。

(2)加密通信算法改變通知,表示隨后的信息都將用「會話秘鑰」加密通信。

(3)客戶端握手結(jié)束通知,表示客戶端的握手階段已經(jīng)結(jié)束。這一項(xiàng)同時把之前所有內(nèi)容的發(fā)生的數(shù)據(jù)做個摘要,用來供服務(wù)端校驗(yàn)。

上面第一項(xiàng)的隨機(jī)數(shù)是整個握手階段的第三個隨機(jī)數(shù),這樣服務(wù)器和客戶端就同時有三個隨機(jī)數(shù),接著就用雙方協(xié)商的加密算法,各自生成本次通信的「會話秘鑰」。

服務(wù)器的最后回應(yīng)

服務(wù)器收到客戶端的第三個隨機(jī)數(shù)( pre-master key )之后,通過協(xié)商的加密算法,計(jì)算出本次通信的「會話秘鑰」。然后,向客戶端發(fā)生最后的信息:

(1)加密通信算法改變通知,表示隨后的信息都將用「會話秘鑰」加密通信。

(2)服務(wù)器握手結(jié)束通知,表示服務(wù)器的握手階段已經(jīng)結(jié)束。這一項(xiàng)同時把之前所有內(nèi)容的發(fā)生的數(shù)據(jù)做個摘要,用來供客戶端校驗(yàn)。

至此,整個 SSL/TLS 的握手階段全部結(jié)束。接下來,客戶端與服務(wù)器進(jìn)入加密通信,就完全是使用普通的 HTTP 協(xié)議,只不過用「會話秘鑰」加密內(nèi)容。
回到qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed,那么這個報(bào)錯,就是缺少加密的手段,也就是沒有提供對HTTP加密的工具,從而無法進(jìn)行HTTPS通信。

6.3 解決方案

那么原因清楚了,就應(yīng)該知道,我們需要把加密這一步缺少的東西給補(bǔ)上。先說一點(diǎn),Qt本身是支持ssl的,但是因?yàn)榉稍??沒有自帶對應(yīng)的dll。

我們先使用這段代碼打印當(dāng)前Qt支持的ssl版本:

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

使用網(wǎng)絡(luò)需要加上Qt的網(wǎng)絡(luò)模塊,在pro文件里加上:

QT += network

我這里輸出的是

"OpenSSL 1.1.1d 10 Sep 2019"

6.4 接下來就去下載OpenSSL,下載方式有兩種:

(1). 下載OpenSSL源碼,自行編譯

https://www.openssl.org/source/

(2). 直接下載dll

Openssl下載網(wǎng)站: http://slproweb.com/products/Win32OpenSSL.html

我推薦第二個方法,省去自己編譯的時間。

然后在這個網(wǎng)站找到對應(yīng)的版本,比如我的版本是剛剛打印的1.1.1,同時,也要注意工程是32位還是64位,我這里選擇的是Win64 OpenSSL v1.1.1n Light,至于EXE還是MSI都沒差異。

6.5 安裝的時候,我選擇的是第二個,這樣可以方便的進(jìn)行dll文件的拷貝。

6.6 進(jìn)入OpenSSL安裝目錄。bin目錄下,拷貝這兩個dll文件到工程的exe程序所在路徑下。

6.7 比如我這里的路徑,直接放到exe根路徑下即可,然后程序即可正常運(yùn)行。

6.8 填寫好正確的郵箱和密碼再次點(diǎn)擊發(fā)送郵件,如果說提示"Authentification Failed"或者提示"Mail sending failed"可能是你填寫的郵箱和密碼錯了.

6.9 下面是郵件發(fā)送成功的截圖:

qq郵箱收到的郵件:

這里我也測試了一下,不同OpenSSL 版本的dll是否可以通用,發(fā)現(xiàn)高低版本都不行,必須得和Qt 打印出來的OpenSSL 版本一致才行。

另外,很多帖子都是說,把這兩個dll文件放到E:\QT\5.12.3\mingw73_64\bin路徑下,即Qt的安裝路徑下。這樣也可以,但是我覺得不好,個人認(rèn)為,盡量別去動Qt安裝路徑下的文件,保證不會被認(rèn)為破壞開發(fā)環(huán)境,或者以后排錯,不會導(dǎo)致當(dāng)時自己把文件放到了Qt安裝路徑下太久忘記,而在別的電腦上無法正常使用的情況。

以上就是Qt實(shí)現(xiàn)編寫SMTP客戶端的示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Qt SMTP客戶端的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論