利用QT实现邮件发送功能使用telnet通过smtp协议来发送邮件
要做一个监测软件,出问题时需要发送一封邮件,所以最近就在网上找了下qt5怎么发邮件,下面贴出方法(代码部分是网上找的一个,自己测试可以使用,直接拷过去就可以了)。
基本原理就是使用telnet通过smtp协议来发送邮件。先简单说下telnet和smtp。
Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。smtp(simple mail transfer protocol)则是简单的邮件传输协议。(具体还是自己去找下度娘吧)
然后就是先熟悉一下telnet怎么发送邮件了首先需要打开电脑的telnet功能,先进入到控制面板界面,点击下图(左)中红框部分,然后在下右图中勾选telnet客户端,点击确定,稍等一下就可以了。
接下来是尝试在telnet中发送邮件:
1.使用telnet连接邮箱服务器,名称的格式基本都是smtp.xxx.com,例如:qq邮箱为smtp.qq.com,163邮箱为smtp.163.com,然后端口为25,如下左图
2.连接上之后会打印上右图第一行,然后输入helo sis,这句只是打招呼,收到250回复之后再输入auth login,收到334回复即可输入用户名,这里需要输入base64格式数据,即需要把你的邮箱先base64编码再输入进来,密码也是一样。(如果是qq邮箱需要先到邮箱-->设置里面打开smtp功能并使用授权码当做密码登陆)
3.登陆完成之后即可开始发送邮件了,如下图mail from会显示在收件人的邮件里面,rcpt to为收件人的邮箱地址,如果要向多个人同时发邮件可使用rcpt to多个邮箱(看到网上这么写的,我并没有试过同时向多个人发邮件)写完数据之后以“回车 . 回车”结束,最后回复250 ok即发送成功(下图中有3此报错,其实我连同下面第4次输入的都是同一个邮箱,这里不太明白为什么会报错)
qt中的实现思路也是如此,下面贴上代码:
先是smtp.c文件:
- #include "smtp.h"
-
- Smtp::Smtp(QString smtphost, QString smtpusername, QString smtppass)
- {
- this->smtphost = smtphost;
- this->smtpusername = smtpusername;
- this->smtppass = smtppass;
- }
-
- bool Smtp::Send( const QString &to, const QString &subject, const QString &body )
- {
- qDebug()<<"####"<<Q_FUNC_INFO;
- bool res = false;
- int waittime = 5 * 1000;
- this->from = smtpusername;
- rcpt = to;
- ErrorMSG.clear();
- Timeout = waittime;
- linesend = 0;
- isconnect = false;
-
-
- QString tmp = "=?utf-8?B?"+ QByteArray().append(subject).toBase64()+"?=";
- message.append("Subject:" + tmp + "\n");
- message.append("To: " + to + "\n");
- message.append("From: "+smtpusername+" <" + smtpusername + ">\n");
-
- message.append("Content-Type: text/html; charset=UTF8;\n"); /* or txt */
- message.append("Content-transfer-encoding: 7BIT\n\n\n\n");
- message.append(body);
- message.replace( tr( "\n" ), tr( "\r\n" ) );
- message.replace( tr( "\r\n.\r\n" ),tr( "\r\n..\r\n" ) );
-
- smtpsocket = new QTcpSocket(this);
- connect( this, SIGNAL(SendLine()), this ,SLOT(PutSendLine()));
- if (smtphost.size() > 0)
- {
- smtpsocket->connectToHost(smtphost,25);
- } else {
- smtpsocket->connectToHost("localhost",25);
- }
- if (smtpsocket->waitForConnected(Timeout))
- {
- if (smtpsocket->waitForReadyRead(Timeout))
- {
- isconnect = true;
- return ReadLiner();
- }
- }
- else
- {
- ErrorCloseAll();
- }
- return res;
- }
-
- bool Smtp::ReadLiner()
- {
- bool res = false;
- if (isconnect)
- {
- QTextCodec *codecx;
- codecx = QTextCodec::codecForMib(106);
- t = new QTextStream( smtpsocket );
- t->setCodec(codecx);
-
- int loops = 0;
- while (!t->atEnd())
- {
- loops++;
- response = t->readLine();
- }
- if (response.size() > 0)
- {
- RemoteServerName = response;
- mailstatus = response.left(3);
- if (mailstatus == "220")
- {
- response="";
- linesend = 1;
- res = true;
- }
- }
- else
- {
- ErrorCloseAll();
- }
- }
- return res;
- }
-
- Smtp::~Smtp()
-
- {
- delete smtpsocket;
- delete t;
- }
-
- /* LINE SENDER */
- bool Smtp::PutSendLine()
- {
- static bool res = true;
- int current = linesend;
- switch(current)
- {
- case 1:
- response = SendLineAndGrab("ehlo localhost");
- if (response.size() > 0)
- {
- ErrorMSG.append(response);
- linesend = 2;
- emit SendLine();
- }
- else
- {
- res=false;
- }
- response ="";
-
- break;
- case 2:
- response = SendLineAndGrab("AUTH LOGIN");
- if (response.size() > 0)
- {
- ErrorMSG.append(response);
- linesend = 3;
- emit SendLine();
- }
- else
- {
- res= false;
- }
- response ="";
-
- break;
- case 3:
- response = SendLineAndGrab(encodeBase64(smtpusername)); /* username send */
- if (response.size() > 0)
- {
- ErrorMSG.append(response);
- if (response.contains("334", Qt::CaseInsensitive))
- {
- linesend = 4;
- emit SendLine();
- }
- }
- else
- {
- res=false;
- }
- response ="";
-
- break;
- case 4:
- response = SendLineAndGrab(encodeBase64(smtppass)); /* pass send */
- if (response.size() > 0)
- {
- ErrorMSG.append(response);
- if (response.contains("235", Qt::CaseInsensitive))
- {
- linesend = 5;
- emit SendLine();
- }
- else
- {
- res= false;
- }
- }
- else
- {
- res= false;
- }
- response ="";
-
- break;
- case 5:
- response = SendLineAndGrab(tr("MAIL FROM: %1").arg(smtpusername));
- if (response.size() > 0)
- {
-
- linesend = 6;
- emit SendLine();
- }
-
- break;
- case 6:
- response = SendLineAndGrab("RCPT TO: "+rcpt);
- if (response.size() > 0)
- {
- ErrorMSG.append(response);
- response ="";
- response = SendLineAndGrab("DATA");
- if (!response.contains("not", Qt::CaseInsensitive))
- {
- ErrorMSG.append(response);
- response ="";
- linesend = 7;
- emit SendLine();
- }
- }
- response ="";
-
- break;
- case 7:
- response = SendLineAndGrab(message+"\r\n.");
- if (response.size() && response.contains("ok", Qt::CaseInsensitive) )
- {
- ErrorMSG.append(response);
- linesend = 8;
- emit SendLine();
- }
- response ="";
-
- break;
- case 8:
- SendLineAndGrab("QUIT");
-
- break;
- default:
-
- break;
- }
- return res;
- }
-
- /* SENDER AND RECIVER */
- QString Smtp::SendLineAndGrab(QString senddata)
- {
- QString incommingData = "";
-
- if (isconnect)
- {
- int current = linesend;
- int loops = 0;
-
- *t << senddata << "\r\n";
- t->flush();
- if (senddata != "QUIT") {
- if (smtpsocket->waitForReadyRead(Timeout))
- {
- while (!t->atEnd())
- {
- loops++;
- QString opera = t->readLine()+"\n";
- incommingData = opera + incommingData;
- }
- }
- } else
- {
-
原文地址:https://blog.csdn.net/qq_16254831/article/details/82748700
- 热门教程
- PHP7报A non well formed numeric value encountered 0
- Linux系统下关闭mongodb的几种命令分享 0
- mongodb删除数据、删除集合、删除数据库的命令 0
- Git&Github极速入门与攻坚实战课程 0
- python爬虫教程使用Django和scrapy实现 0
- libnetsnmpmibs.so.31: cannot open shared object file 0
- 数据结构和算法视频教程 0
- redis的hash结构怎么删除数据呢? 0
- C++和LUA解析器的数据交互实战视频 0
- mongodb errmsg" : "too many users are authenticated 0
- C++基础入门视频教程 0
- 用30个小时精通C++视频教程可能吗? 0
- C++分布式多线程游戏服务器开发视频教程socket tcp boost库 0
- C++培训教程就业班教程 0
- layui的util工具格式时间戳为字符串 0
- C++实战教程之远程桌面远程控制实战 1
- 网络安全培训视频教程 0
- LINUX_C++软件工程师视频教程高级项目实战 0
- C++高级数据结构与算法视频教程 0
- 跨域问题很头疼?通过配置nginx轻松解决ajax跨域问题 0
- 相关文章
- 【译】JavaScript数据结构(3):单向链表与双向链表 16
- 10个JavaScript难点 16
- 【译】苹果拒绝支持PWA,有损Web的未来 16
- iView 一周年了,同时发布了 2.0 正式版,但这只是开始... 16
- nodejs+mongodb构建一个简单登录注册功能 16
- 【译】JavaScript数据结构(4):树 16
- 组件化开发与黑箱 16
- TypeScript - 不止稳,而且快 16
- webpack3+anujs+ReactCSSTransitionGroup 16
- 原生js实现图片放大镜效果 16
- WEB缓存探究第二弹——实战 16
- 纯笔记:vfork 的一些使用场景(顺便讲一下 fork 的原理) 16
- Android APP 内部捐赠实现(支付宝&微信) 16
- WKWebView 的一些小总结 16
- 模型评价(一) AUC大法 16
- 开始使用GraphQL 16
- Webpack模块化原理简析 16
- gulp使用问题记录 16
- 使用Angular4动画为页面添彩 16
- Python27 Matplotlib (win64 python2.7) 安装及简单使用 16