send mail from qt app problem
hi all...
i'm currently developing an application that will send an email. ive'd search the forum for the similar topics, and found out some.
i used the smtp code:
smtp.cpp
Quote:
#include "smtp.h"
#include <QAbstractSocket>
Smtp::Smtp( const QString &strmailserver, const int &port, 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( disconnected()), 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( strmailserver , port);
if(socket->waitForConnected ( 10000 )){
qDebug("connected");
}
t = new QTextStream( socket );
}
void Smtp::stateChanged(QAbstractSocket::SocketState socketState)
{
qDebug() <<"stateChanged " << socketState;
}
void Smtp::errorReceived(QAbstractSocket::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 = "";
}
Smtp::~Smtp()
{
delete t;
delete socket;
}
smtp.h
Quote:
#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 &strmailserver, const int &port, const QString &from, const QString &to,
const QString &subject, const QString &body );
~Smtp();
signals:
void status( const QString &);
private slots:
void stateChanged(QAbstractSocket::SocketState socketState);
void errorReceived(QAbstractSocket::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
i call the class with this parameters:
Quote:
Smtp *sendMail = new Smtp( "my-mail-server", 25, "myemail@yahoo.com","receiveremail@yahoo.com", "Subject", "This is the message.");
delete sendMail;
during runtime the debug output is:
Quote:
stateChanged QAbstractSocket::HostLookupState
stateChanged QAbstractSocket::ConnectingState
stateChanged QAbstractSocket::ConnectedState
Connected
connected
stateChanged QAbstractSocket::ClosingState
stateChanged QAbstractSocket::UnconnectedState
disconneted
now, i check my email and i havent receive any mail. is there anyone here who knows how to fix this? thnks a lot..
Re: send mail from qt app problem
Well, Smtp is working with signals/slots and is asynchronous. (It needs an QEventLoop running.)
You delete the object right after creating it. You connect in the constructor (wait for some reasing synchronously for the connection to be established). Then you exit the constructor and the caller immediately deletes to smtp object. This a) causes a disconnect (good thing) and b) obviously prevents any data from being read in your read-Slot etc.
Just do not delete the object (at least not until you're done).
Re: send mail from qt app problem
thnks.. its finally working.. i checked my code and found out that when i call the smtp class, i used delete sendMail which is wrong..
Re: send mail from qt app problem
hi! all, another question..
using the smtp class, im trying to send mail to multiple recipients, that is, each email add is separated by a semi colon ';', but during runtime an error occured,
Quote:
Unexpected reply from SMTP server: 500 Syntax error, command unrecognized
is there anyone here knows how to solve this error or knows another way to send email to multiple recipients, also with cc(carbon copy)?
thank you very much!
Re: send mail from qt app problem
It's possible to attach file?
Re: send mail from qt app problem
its clearly a command error..which means the data u r sending is wrong or formatted wrongly..hv a look at example of expanding a mailing list in:
http://www.ietf.org/rfc/rfc0821.txt
this will give a much better insight into everything u are doing and u'll be able to debug well.
Re: send mail from qt app problem
Hi,
I too am using the same code for mailing. But I am still not able to send any mail. When I run the app, it is stayed on Connected state not going any further. I would be grateful to any help.
Code:
#include "smtp.h"
{
connect( socket, SIGNAL(readyRead()), this, SLOT( readyRead() ) );
connect( socket, SIGNAL( connected() ), this, SLOT( connected() ) );
connect(socket, SIGNAL(disconnected()), 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;
this->Maddress = to.mid( to.indexOf('@',1)+1);
s.append(this->Maddress);
socket->connectToHost( s , 465);
if(socket->waitForConnected ( 40000 )) {qDebug("connected"); }
}
Smtp::~Smtp()
{
delete t;
delete socket;
}
{
qDebug() <<"stateChanged " << socketState;
}
{
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
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 = "";
}
#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(QAbstractSocket::SocketState socketState);
void errorReceived(QAbstractSocket::SocketError socketError);
void disconnected();
void connected();
void readyRead();
private:
QString message;
QTextStream *t;
QTcpSocket *socket;
QString from;
QString rcpt;
QString Maddress;
QString response;
enum states{Rcpt,Mail,Data,Init,Body,Quit,Close};
int state;
};
#endif
Quote:
stateChanged QAbstractSocket::HostLookupState
stateChanged QAbstractSocket::ConnectingState
stateChanged QAbstractSocket::ConnectedState
Connected
connected
I am trying to send mail to xxx@gmail.com and from xx@hotmail.com
Thank you,
Baluk
Re: send mail from qt app problem
Your code is flawed. You can not assume that every mail server starts with 'smtp' and ends with a part of the users mail address.
You will have to do a proper mail exchanger lookup and connect to that host instead. This doesn't cure all your problems however, as lots of servers block connections from ADSL/Cable IP addresses. To only way around this is to run your own server and connect to that one.
Re: send mail from qt app problem
Furthermore many servers reject email the first time it is sent and you have to resend it after some grace time. This is called graylisting. Some servers will just reject your mail because it is being sent from a wrong ip, etc.
If you want to send mails directly from your application, you should be connecting to a server you know will accept your mail and then let it handle the mail routing. Then you don't have to do any server lookups and such.
Re: send mail from qt app problem
Hello all! First I want to thank all of you. This information has been very helpful. With some minor modifications, I am now able to send an email via SMTP. The code that I am using was pasted from this forum and tweaked to get it to work with Qt4.6.2.
I am having one issue though - my body text never gets transferred! What is happening? I get a subject line, but no body text. My ultimate goal is to attach a file, but I am a bit worried about accomplishing that if I cannot even get my body text to show up!
It is this part of the code that I really do not understand. 1) Does it have to be done in this manner? 2) What is the purpose of the replaces? 3) How is SMTP getting my Subject Text, but not my Body Text? Any help is appreciated. (P.S. I am going to post this on another thread in order to make sure it gets seen).
Code:
...
sMessage = "To: " + to + "\n";
sMessage.append("From: " + from + "\n");
sMessage.append("Subject: " + subject + "\n");
sMessage.append(body);
sMessage.
replace( QString::fromLatin1( "\n" ),
QString::fromLatin1( "\r\n" ) );
sMessage.
replace( QString::fromLatin1( "\r\n.\r\n" ),
QString::fromLatin1( "\r\n..\r\n" ) );
sFrom = from;
sTo = to;
...}
Re: send mail from qt app problem
There needs to be an empty line between the last header ("Subject" in your case) and first line of the body of the message.
Quote:
(P.S. I am going to post this on another thread in order to make sure it gets seen).
Please don't do that. We can see your message very well.
Re: send mail from qt app problem
Quote:
Originally Posted by
wysota
There needs to be an empty line between the last header ("Subject" in your case) and first line of the body of the message.
Excellent! Here are the results. I tried:
Code:
sMessage.append("Subject: " + subject + "\n");
sMessage.append("\r\n" + body);
which yielded body text and I tried:
Code:
sMessage.append("Subject: " + subject + "\r\n");
sMessage.append(body);
which also yielded body text. It seems that the "\r" is missing from all of the code snippets in the thread. Thank you! Btw, I am also getting:
X-UIDL: 576795945
X-IMail-ThreadID: b5a1038d0000ddec
appended to the end of my body text. What is that?
Quote:
Please don't do that. We can see your message very well.
Yes sir. :o
Re: send mail from qt app problem
The \r are not missing at all, they are implemented near the end:
Code:
sMessage.
replace( QString::fromLatin1( "\n" ),
QString::fromLatin1( "\r\n" ) );