Is there a simple way to send email using Qt?
I see that it can be done by using ActiveQt to control Outlook. I am not interested in doing this. Is there another way?
Printable View
Is there a simple way to send email using Qt?
I see that it can be done by using ActiveQt to control Outlook. I am not interested in doing this. Is there another way?
You might try this: http://www.qtcentre.org/forum/showthread.php?t=183
Depending on the version of QT, the 3.x series had a smtp mail example in the "networking" examples.Quote:
Originally Posted by johnny_sparx
The modified structure for QT 4.x is below:
smtp.h
Code:
/**************************************************************************** ** $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> { Q_OBJECT public: ~Smtp(); signals: private slots: 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.cpp
Code:
#include "smtp.h" { connect( socket, SIGNAL( readyRead() ), this, SLOT( readyRead() ) ); connect( socket, SIGNAL( connected() ), this, SLOT( connected() ) ); connect( socket, SIGNAL(error(SocketError)), this, SLOT(errorReceived(SocketError))); connect( socket, SIGNAL(stateChanged( SocketState)), this, SLOT(stateChanged(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); this->from = from; rcpt = to; state = Init; socket->connectToHost( "smtp.yourserver.com", 25); if(socket->waitForConnected ( 30000 )) {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 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 = ""; }
To send a mail just use:
Code:
Smtp *newMail = new Smtp("from@address.com","to@address.com"," Your Subject","My body text"); delete newMail;
Please note: change the server address in "smtp.cpp" to your local server, most of the time localhost will work.. remote hosts should also work though.
As well, this may not work right off the bat, i speciallized it to work for my program.. i just hacked it back together for an example. The code is essentially correct, i just usually include the "To: BLAH\n", "From: BLAH\n" and "Subject: BLAH\n" within my message body.. so if there is something wrong it should be in that area.
Good Luck!
J
Hi guys,
I am working on a SMTP client too and I do quite the same things as in the Qt example (btw. I didnt remember there was such an example ;) ).
The problem is my app won't connect if I don't call waitForConnected()!
But isnt this method useless if we wand non-blocking sockets?
Other code examples simply call connectToHost(...) after setting up the right connections.
If I don't call waitForConnected() the socket status remains on LookingUpHost (or whatever the exact name is)
Any clue???
Maybe you block the event loop? Do you check socket's status in some kind of a loop?Quote:
Originally Posted by blue.death
No, i connected the stateChanged() signal to a slot so I can keep track of the state changes.Quote:
Originally Posted by jacek
If I don't call waitForConnected the state remains 1 and never changes.
If i call waitForConnected the connected() signal is emitted and the state changes to 2 and then 3 (connected).
Do you have "QT += network" in your .pro file? Do you use threads? Maybe there's a loop that blocks the event loop in some other place?Quote:
Originally Posted by blue.death
.pro file is ok, otherwise it wouldnt build at all,Quote:
Originally Posted by jacek
no threads, thats why i dont want blocking sockets,
and no event loop blocks ;)
I'm starting to think it's a problem with my Qt 4.1.3 on windoze.
I will see if i can post some code tomorrow.. i need some sleep now
I rewrite the troll sample to make SMTP AUTH LOGIN work on qmail & postix tested...
Important is the mail date ..... the troll sample go unixtime zero 1970....
Code:
{ QDateTime fromunix; fromunix.setTime_t(unixtime); bool ok; return (int)numeric.toFloat(&ok); } { /* mail rtf Date format! http://www.faqs.org/rfcs/rfc788.html */ uint unixtime = (uint)time( NULL ); 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"; /*qDebug() << "### RTFdays " << RTFdays.at(timeroad.dayOfWeek()); qDebug() << "### RTFmonth " << RTFmonth.at(dateswap("M",unixtime)); qDebug() << "### yyyy " << dateswap("yyyy",unixtime); qDebug() << "### M " << dateswap("M",unixtime); qDebug() << "### d " << 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(" "); rtfd_line.append(RTFmonth.at(dateswap("M",unixtime))); rtfd_line.append(" "); rtfd_line.append(" "); rtfd_line.append(fromunix.toString("hh:mm:ss")); rtfd_line.append(""); /*qDebug() << "### mail rtf Date format " << rtfd_line.join("");*/ }
Quote:
Originally Posted by blue.death
The example was only in the QT 3.x series under networking examples, i just altered it to work in QT 4.x.
My understanding of the "waitForConnected()" function is that it's simply a delay to allow a handshake to occur, it doesn't actually do anything unless you want to establish a timeout (lets say for a server that's offline) and take the bool return to do error correction.
Basically it is a delay before completing the socket.
I removed the "waitForConnected()" from my client and it established a connection immediately, but my mail server is also on the company lan and connects extremely quickly.
Using the "waitForConnected()" function should have no effect on how you connect unless you choose to implement error correction based on it's return.
If you don't want to use it then i suggest putting a delay in, something like 10-15 seconds, which is close to a worst case connection delay for most internet applications.
Of course if you use "waitForConnected(15000)" then it will automatically stop the delay after either 15 seconds (a timeout) or you establish a connection (if it's less than the passed 15 seconds), which would make sense to minimize the time your application is waiting.
J
Even this Post is old, it was very usefull for me. So a big thank you!!
But i have to notes for using MS Exchange Server (in my case Version 2000).
You have to change two things inside the code:
- Don´t remove
or no mails will be send. Instead decrease the timeout, i.e. 500.Code:
if (smtpsocket->waitForConnected(Timeout))
- In function "PutSendLine()", in step "case 4"
replace the response "ok" with "Authentication successful" because this is the real responce and it wont work else.
Hello,
I'm newbie and I'd like to understand correctly this code.
Could you write what is the "output" is it sth. like stdout?:
Code:
void Smtp::connected() { output->append("connected"); qDebug() << "Connected "; }
thanks
I used the structure from the post #9, taking into account post #11 (especially the second note). I am successfully connecting to the server and sending it those "lines" until it comes to send line number 7 (function PutSendLine(), case 7) - it's an actual message. After this line:
I'm receiving such a response from a server:Code:
response = SendLineAndGrab(message+"\r\n.");
I have tried to remove the date (by commenting one of the first lines in smtp.cpp), but then I received similar response but this time it was aobut "User-Agent: Mozilla Thunderbird 1.0.6...".Quote:
"550 5.5.2 Unknown command 'Date: Mon, 8 Mar 2010 15:54:26'
Why is the server sending such responses? How to make it work?
in step 5
SendLineAndGrab("MAIL FROM: "+from);
someserver return:
501 Bad address syntax
so this line must chang to:
SendLineAndGrab("MAIL FROM:<"+from+">");
How can we add to this code an option to send attached files?
7-bit encode the attachments using something like Base64 and then attach them to the body of the email as a MIME attachment making sure that the message and each attachment has a different id so that the receiving email client knows how to seperate the parts again.
See POCO Libraries, its very helpfull
http://pocoproject.org
OK nielsenj demonstrated a nice axample how to send a mail via SMTP. But I can't find on the internet how to get the mail which is sent by the code of nielsenj.
Hi nielsenj,
I hope you are still active in this forum. I am new to Qt and I have the issue with smtp client. I have fallowed your code and am able to get the connected signal but immediately I am getting disconnected signal. Do you have any Idea why it is happening. I would be grateful to any help.
Thank you,
Baluk