美文网首页
QT使用SMTP实现发送简单中文文本邮件

QT使用SMTP实现发送简单中文文本邮件

作者: wuguandong | 来源:发表于2019-10-12 13:35 被阅读0次

    使用telnet发送邮件

    通过使用cmd下的telnet发送一封邮件,掌握SMTP发送邮件的过程。

    1. 准备工作

    • 对发送方邮箱地址进行base64编码。
    • 对发送方邮箱授权码进行base64编码。

    Python进行base64编码方法:

    >>> import base64
    >>> base64.b64encode(b"123456@163.com") # b表示使用ascii对字符串进行编码
    b'MTIzNDU2QDE2My5jb20='
    

    2. 发送邮件

    1. 打开cmd

    2. 输入telnet smtp.163.com 25

    3. 进入telnet后,依次输入以下内容

      helo 163.com # 打招呼
      auth login # 登录命令
      MTIzNDU2QDE2My5jb20= # base64编码后的发送方邮箱地址
      MTIzNDU2 # base64编码后的发送方邮箱授权码
      mail from: <vfyouv655@163.com> # 注明发件人
      rcpt to: <963312591@qq.com> # 注明收件人
      data # 表示接下来开始输入数据部分
      from:vfyouv655@163.com # 注明发件人
      to:963312591@qq.com # 注明收件人
      subject:Test # 输入邮件主题
                   # 一个空行
      i am testing to send mail # 邮件正文
                   # 一个空行
      . # 表示邮件内容输入结束
      
    4. 正常情况结果如下图所示


    使用QT实现以上内容

    记得在.pro文件中引入network模块。下面直接上代码。

    widget.h文件内容

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    #include <QTcpSocket>
    #include <QAbstractSocket>
    #include <QMessageBox>
    #include <QDebug>
    
    namespace Ui {
    class Widget;
    }
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        explicit Widget(QWidget *parent = nullptr);
        ~Widget();
    
    private slots:
        void readyReadSlot();
    
    private:
        //检查连接状态
        void checkConnectState();
        //发送helo
        void sendHelo();
        //发送auth login
        void sendAuthLogin();
        //发送用户名
        void sendUser();
        //发送密码
        void sendPassword();
        //发送mail from
        void sendMailFrom();
        //发送rcpt to
        void sendRcptTo();
        //发送data
        void sendData();
        //发送邮件内容
        void sendContent();
        //发送成功后续操作
        void afterSendSuccess();
    
    private:
        Ui::Widget *ui;
    
        QString senderMail; //发送方邮箱地址
        QString authCode; //发送方邮箱授权码
        QString receiveMail; //接收方邮箱地址
    
        QString title; //邮件标题
        QString content; //邮件正文
    
        QString expectedReply; //期待收到的应答
        void (Widget::*nextAction)(); //收到正确应答后下一步要执行的方法
    
        QTcpSocket *tcpSocket;
    };
    
    #endif // WIDGET_H
    

    widget.cpp文件内容

    #pragma execution_character_set("utf-8")
    #include "widget.h"
    #include "ui_widget.h"
    
    Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget),
        senderMail("这里填写发送方邮箱地址"), authCode("这里填写发送方邮箱授权码"), receiveMail("这里填写接收方邮箱地址"),
        expectedReply("220 163.com Anti-spam GT for Coremail System"), nextAction(&Widget::checkConnectState)
    {
        ui->setupUi(this);
    
        //设置邮件的标题和正文
        this->title = "这是邮件标题";
        this->content = "这句话是邮件的正文";
    
        //tcpSocket初始化
        this->tcpSocket = new QTcpSocket(this);
        tcpSocket->connectToHost("smtp.163.com", 25);
        connect(tcpSocket, &QTcpSocket::readyRead,this, &Widget::readyReadSlot);
    }
    
    Widget::~Widget()
    {
        delete ui;
    }
    
    void Widget::readyReadSlot()
    {
        QByteArray buffer = tcpSocket->readAll();
        qDebug()<<"收到服务器回复:"<<buffer;
    
        if(buffer.contains(this->expectedReply.toLatin1())){
            if(nextAction) (this->*nextAction)();
        }
        else{
            QMessageBox::warning(this, "提示", "邮件发送失败!");
        }
    }
    
    //检查连接状态
    void Widget::checkConnectState()
    {
        if(tcpSocket->state() == QAbstractSocket::ConnectedState){
            sendHelo();
        }
        else{
            QMessageBox::warning(this, "提示", "连接失败!");
        }
    }
    
    //发送helo
    void Widget::sendHelo()
    {
        QString str = "helo 163.com\r\n";
        qDebug()<<"向服务器发送: " + str;
        tcpSocket->write(str.toLatin1());
        this->expectedReply = "250 OK\r\n";
        this->nextAction = &Widget::sendAuthLogin;
    }
    
    //发送auth login
    void Widget::sendAuthLogin()
    {
        QString str = "auth login\r\n";
        qDebug()<<"向服务器发送: " + str;
        tcpSocket->write(str.toLatin1());
        this->expectedReply = "334 dXNlcm5hbWU6\r\n";
        this->nextAction = &Widget::sendUser;
    }
    
    //发送用户名
    void Widget::sendUser()
    {
        QString str = QString("\r\n").prepend(senderMail.toLatin1().toBase64());
        qDebug()<<"向服务器发送: " + str;
        tcpSocket->write(str.toLatin1());
        this->expectedReply = "334 UGFzc3dvcmQ6\r\n";
        this->nextAction = &Widget::sendPassword;
    }
    
    //发送密码
    void Widget::sendPassword()
    {
        QString str = QString("\r\n").prepend(authCode.toLatin1().toBase64());
        qDebug()<<"向服务器发送: " + str;
        tcpSocket->write(str.toLatin1());
        this->expectedReply = "235 Authentication successful\r\n";
        this->nextAction = &Widget::sendMailFrom;
    }
    
    //发送mail from
    void Widget::sendMailFrom()
    {
        QString str = QString("mail from: <%1>\r\n").arg(senderMail);
        qDebug()<<"向服务器发送: " + str;
        tcpSocket->write(str.toLatin1());
        this->expectedReply = "250 Mail OK\r\n";
        this->nextAction = &Widget::sendRcptTo;
    }
    
    //发送rcpt to
    void Widget::sendRcptTo()
    {
        QString str = QString("rcpt to: <%1>\r\n").arg(receiveMail);
        qDebug()<<"向服务器发送: " + str;
        tcpSocket->write(str.toLatin1());
        this->expectedReply = "250 Mail OK\r\n";
        this->nextAction = &Widget::sendData;
    }
    
    //发送data
    void Widget::sendData()
    {
        QString str = "data\r\n";
        qDebug()<<"向服务器发送: " + str;
        tcpSocket->write(str.toLatin1());
        this->expectedReply = "354 End data with <CR><LF>.<CR><LF>\r\n";
        this->nextAction = &Widget::sendContent;
    }
    
    //发送邮件内容
    void Widget::sendContent()
    {
        QString str = QString("from:%1\r\n"
                              "to:%2\r\n"
                              "subject:=?UTF-8?B?%3?=\r\n"
                              "\r\n"
                              "%4\r\n"
                              "\r\n"
                              ".\r\n").arg(senderMail).arg(receiveMail).arg( QString("").append(title.toUtf8().toBase64()) ).arg(content);
        qDebug()<<"向服务器发送: " + str;
        tcpSocket->write(str.toUtf8());
        this->expectedReply = "250 Mail OK queued as";
        this->nextAction = &Widget::afterSendSuccess;
    }
    
    //发送成功后续操作
    void Widget::afterSendSuccess()
    {
        QMessageBox::information(this, "提示", "邮件发送成功!");
    }
    

    相关文章

      网友评论

          本文标题:QT使用SMTP实现发送简单中文文本邮件

          本文链接:https://www.haomeiwen.com/subject/ggftyctx.html