qt5發送郵件

要做一個監測軟件,出問題時需要發送一封郵件,所以最近就在網上找了下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
        {
            delete smtpsocket;
            delete t;
            isconnect = false;
            return incommingData;
        }
    }
    else
    {
         ErrorCloseAll();
    }
    return incommingData;
}


QString Smtp::encodeBase64( QString xml )
{
    QByteArray text;
    text.append(xml);
    return text.toBase64();
}

QString Smtp::decodeBase64( QString xml )
{
    QByteArray xcode("");;
    xcode.append(xml);
    QByteArray precode(QByteArray::fromBase64(xcode));
    QString notetxt = precode.data();
    return notetxt;
}



int Smtp::dateswap(QString form, uint unixtime )
{
    QDateTime fromunix;
    fromunix.setTime_t(unixtime);
    QString numeric = fromunix.toString((const QString)form);
    bool ok;
    return (int)numeric.toFloat(&ok);
}


QString Smtp::TimeStampMail()
{
    /* mail rtf Date format! http://www.faqs.org/rfcs/rfc788.html */
    QDateTime timer1( QDateTime::currentDateTime() );

    uint unixtime = timer1.toTime_t();
    QDateTime fromunix;
    fromunix.setTime_t(unixtime);


    QStringList RTFdays = QStringList() << "giorno_NULL" << "Mon" << "Tue" << "Wed" << "Thu" << "Fri" << "Sat" << "Sun";
    QStringList RTFmonth = QStringList() << "mese_NULL" << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun" << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";
    QDate timeroad(dateswap("yyyy",unixtime),dateswap("M",unixtime),dateswap("d",unixtime));

    QStringList rtfd_line;
    rtfd_line.clear();
    rtfd_line.append("Date: ");
    rtfd_line.append(RTFdays.at(timeroad.dayOfWeek()));
    rtfd_line.append(", ");
    rtfd_line.append(QString::number(dateswap("d",unixtime)));
    rtfd_line.append(" ");
    rtfd_line.append(RTFmonth.at(dateswap("M",unixtime)));
    rtfd_line.append(" ");
    rtfd_line.append(QString::number(dateswap("yyyy",unixtime)));
    rtfd_line.append(" ");
    rtfd_line.append(fromunix.toString("hh:mm:ss"));
    rtfd_line.append(" +0100");
    return QString(rtfd_line.join(""));
}

void Smtp::ErrorCloseAll()
{
    delete t;
    smtpsocket->close();
}

接下來smtp.h

#ifndef SMTP_H
#define SMTP_H

#include<QtCore>
#include<QObject>
#include<QCoreApplication>

#include <QTcpSocket>
#include <QString>
#include <QTextStream>
#include <QDebug>
#include <QAbstractSocket>
#include <QDateTime>
#include <QDate>
#include <QLocale>
#include <QObject>
#include <QTcpSocket>

class Smtp:public QObject
{
    Q_OBJECT

public:
    Smtp(QString smtphost,QString smtpusername,QString smtppass);
    ~Smtp();
    bool Send( const QString &to,const QString &subject, const QString &body );
    int linesend;
    QStringList ErrorMSG;
    bool ReadLiner();
    void ErrorCloseAll();

signals:
   void status( const QString &);
   void SendLine();

public slots:
   bool PutSendLine();

private:
    bool isconnect;
    QString smtphost;
    QString smtpusername;
    QString smtppass;
    QString message;
    QString output;
    QString RemoteServerName;
    QString mailstatus;
    QTextStream *t;
    QTcpSocket *smtpsocket;
    QString from;
    QString rcpt;
    QString response;
    QString SendLineAndGrab(QString senddata);
    int Timeout;
    QString encodeBase64( QString xml );
    QString decodeBase64( QString xml );
    int dateswap(QString form, uint unixtime );
    QString TimeStampMail();
};

#endif // SMTP_H

另外還有需要注意的地方:

1.如果郵件中出現中文亂碼,那麼可以在文件的前面加上代碼就可以了

#pragma execution_character_set("utf-8")

2.點pro文件中需要加入network模塊 

3.如果郵箱中需要換行使用<br>而不是\r\n

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章