I cannot send email by Qt



  • Hi,

    I cannot send email by Qt.

    Output:
    @Connecting...
    Error: "Socket operation timed out"@

    Email.pro
    @
    #-------------------------------------------------

    Project created by QtCreator 2013-08-20T20:51:19

    #-------------------------------------------------

    QT += core network

    QT += gui

    TARGET = Email
    CONFIG += console
    CONFIG -= app_bundle

    TEMPLATE = app

    SOURCES += main.cpp
    smtp.cpp

    HEADERS +=
    smtp.h
    @

    main.cpp
    @
    #include <QCoreApplication>
    #include "smtp.h"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);

    //Smtp *newMail  = new Smtp("from@address.com","to@address.com",
    //" Your Subject","My body text");
    
    Smtp *newMail  = new Smtp("super.8observer8-001@yandex.ru",
                              "8observer8@gmail.com",
                              " Your Subject","My body text");
    delete newMail;
    
    return a.exec&#40;&#41;;
    

    }
    @

    smtp.h
    @
    /****************************************************************************
    ** $Id: qt/smtp.h 3.3.6 edited Aug 31 2005 $
    **
    ** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
    **
    ** This file is part of an example program for Qt. This example
    ** program may be used, distributed and modified without limitation.
    **
    *****************************************************************************/

    #ifndef SMTP_H
    #define SMTP_H

    #include <QTcpSocket>
    #include <QString>
    #include <QTextStream>
    #include <QDebug>
    #include <QMessageBox>

    class Smtp : public QObject
    {
    Q_OBJECT

    public:
    Smtp( const QString &from, const QString &to,
    const QString &subject, const QString &body );
    ~Smtp();

    signals:
    void status( const QString &);

    private slots:
    void stateChanged(QTcpSocket::SocketState socketState);
    void errorReceived(QTcpSocket::SocketError socketError);
    void disconnected();
    void connected();
    void readyRead();

    private:
    QString message;
    QTextStream *t;
    QTcpSocket *socket;
    QString from;
    QString rcpt;
    QString response;
    enum states{Rcpt,Mail,Data,Init,Body,Quit,Close};
    int state;

    };
    #endif // SMTP_H
    @

    smtp.cpp
    @
    #include "smtp.h"

    Smtp::Smtp( const QString &from, const QString &to, const QString &subject, const QString &body )
    {
    socket = new QTcpSocket( this );

    connect( socket, SIGNAL( readyRead() ), this, SLOT( readyRead() ) );
    connect( socket, SIGNAL( connected() ), this, SLOT( connected() ) );
    connect( socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
        SLOT(errorReceived(QAbstractSocket::SocketError)));
    connect( socket, SIGNAL(stateChanged( QAbstractSocket::SocketState)), this,
        SLOT(stateChanged(QAbstractSocket::SocketState)));
    connect(socket, SIGNAL(disconnectedFromHost()), this,
        SLOT(disconnected()));;
    
    message = "To: " + to + "\n";
    message.append("From: " + from + "\n");
    message.append("Subject: " + subject + "\n");
    message.append(body);
    message.replace( QString::fromLatin1( "\n" ), QString::fromLatin1( "\r\n" ) );
    message.replace( QString::fromLatin1( "\r\n.\r\n" ),
    QString::fromLatin1( "\r\n..\r\n" ) );
    this->from = from;
    rcpt = to;
    state = Init;
    socket->connectToHost( "google.com", 25); // smtp.yourserver.com
    if(socket->waitForConnected ( 30000 ))  {qDebug("connected");  }
    
    t = new QTextStream( socket );
    

    }
    Smtp::~Smtp()
    {
    delete t;
    delete socket;
    }
    void Smtp::stateChanged(QTcpSocket::SocketState socketState)
    {

    qDebug() <<"stateChanged " << socketState;
    

    }

    void Smtp::errorReceived(QTcpSocket::SocketError socketError)
    {
    qDebug() << "error " <<socketError;
    }

    void Smtp::disconnected()
    {

    qDebug() <<"disconneted";
    qDebug() << "error "  << socket->errorString();
    

    }

    void Smtp::connected()
    {
    //output->append("connected");
    qDebug() << "Connected ";
    }

    void Smtp::readyRead()
    {

     qDebug() <<"readyRead";
    // SMTP is line-oriented
    
    QString responseLine;
    do
    {
        responseLine = socket->readLine();
        response += responseLine;
    }
    while ( socket->canReadLine() && responseLine[3] != ' ' );
    
    responseLine.truncate( 3 );
    
    
    if ( state == Init && responseLine[0] == '2' )
    {
        // banner was okay, let's go on
    
        *t << "HELO there\r\n";
        t->flush();
    
        state = Mail;
    }
    else if ( state == Mail && responseLine[0] == '2' )
    {
        // HELO response was okay (well, it has to be)
    
        *t << "MAIL FROM: " << from << "\r\n";
        t->flush();
        state = Rcpt;
    }
    else if ( state == Rcpt && responseLine[0] == '2' )
    {
    
        *t << "RCPT TO: " << rcpt << "\r\n"; //r
        t->flush();
        state = Data;
    }
    else if ( state == Data && responseLine[0] == '2' )
    {
    
        *t << "DATA\r\n";
        t->flush();
        state = Body;
    }
    else if ( state == Body && responseLine[0] == '3' )
    {
    
        *t << message << "\r\n.\r\n";
        t->flush();
        state = Quit;
    }
    else if ( state == Quit && responseLine[0] == '2' )
    {
    
        *t << "QUIT\r\n";
        t->flush();
        // here, we just close.
        state = Close;
        emit status( tr( "Message sent" ) );
    }
    else if ( state == Close )
    {
        deleteLater();
        return;
    }
    else
    {
        // something broke.
        QMessageBox::warning( 0, tr( "Qt Mail Example" ), tr( "Unexpected reply from SMTP server:\n\n" ) + response );
        state = Close;
    }
    response = "";
    

    }
    @

    This code is from: http://www.qtcentre.org/threads/2221-Sending-email-using-Qt

    Thank you!



  • Hi,
    You delete the newMail before the eventloop is started? Might be better to connect a signal when mail was send and in that slot delete the newMail object?
    Greetz


  • Moderators

    the server address for sending an email via an gmail account is not "google.com" but "smtp.gmail.com".

    And you also don't provide your credentials to log in with your google account. Since i don't think that google provides a free spamming-slingshot SMTP server for free it would be pure magic that your code would work ;)

    I also believe that SSL is required by google.

    So you would be better off by using "QxtSmtp":http://libqxt.bitbucket.org/doc/tip/qxtsmtp.html.



  • Guys, thank you!

    Is this right arguments?

    @private slots:
    void stateChanged(QAbstractSocket::SocketState socketState);
    void errorReceived(QAbstractSocket::SocketError socketError);
    void disconnected();
    @

    @
    connect( socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
    SLOT(errorReceived(QAbstractSocket::SocketError)));
    connect( socket, SIGNAL(stateChanged( QAbstractSocket::SocketState)), this,
    SLOT(stateChanged(QAbstractSocket::SocketState)));
    connect(socket, SIGNAL(disconnectedFromHost()), this,
    SLOT(disconnected()));;
    @

    @
    void Smtp::stateChanged(QAbstractSocket::SocketState socketState) {
    }
    @

    @
    void Smtp::errorReceived(QAbstractSocket::SocketError socketError) {
    }
    @

    @
    void Smtp::disconnected() {
    }
    @

    I changed:
    @
    socket->connectToHost( "smtp.gmail.com", 25); // smtp.yourserver.com
    @

    Output
    @
    Object::connect: No such signal QTcpSocket::disconnectedFromHost() in ../Email/s
    mtp.cpp:13
    stateChanged QAbstractSocket::HostLookupState
    stateChanged QAbstractSocket::ConnectingState
    stateChanged QAbstractSocket::ConnectedState
    Connected
    connected
    stateChanged QAbstractSocket::UnconnectedState@


  • Moderators

    as the error message says: ther is no such signal "disconnectedFromHost()" it's "disconnected()".

    But nevertheless you wont be able to connect to gmail's smtp server without authentication.
    Or to be more precise you will be able to connect to the socket but not be able to send a mail (unless you are hiding the authentication code from us).

    You may receive some error message from google's server on your socket.



  • Thank you!

    I changed:
    @
    connect(socket, SIGNAL(disconnected()), this,
    SLOT(disconnected()));;
    @

    Output:
    @
    stateChanged QAbstractSocket::HostLookupState
    stateChanged QAbstractSocket::ConnectingState
    stateChanged QAbstractSocket::ConnectedState
    Connected
    connected
    stateChanged QAbstractSocket::UnconnectedState
    disconneted
    error "Unknown error"
    @

    How to authenticate?


  • Moderators

    you will need to implement the SMTP authentication yourself. Meaning sending the right data and interpret the responses correct.

    Or you use the QxtSmtp as i already suggested before.

    [quote author="raven-worx" date="1377783072"]
    So you would be better off by using "QxtSmtp":http://libqxt.bitbucket.org/doc/tip/qxtsmtp.html.[/quote]

    It also supports SSL and authentication and the API is much cleaner to use.



  • Thank you! I will use QxtSmtp.

    you will need to implement the SMTP authentication yourself
    How to do this in my case?



  • I will rewrite my code with class QxtSmtp.

    Thank you very much :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.