Sending email via SMTP in different thread |
Здравствуйте, гость ( Вход | Регистрация )
Sending email via SMTP in different thread |
CbIHOK |
15.6.2010, 7:11
Сообщение
#1
|
Новичок Группа: Новичок Сообщений: 1 Регистрация: 15.6.2010 Пользователь №: 1807 Спасибо сказали: 0 раз(а) Репутация: 0 |
Коллеги, столкнулся с какой-то проблемой при реализации простенького SMTP. Собственно протокол класса:
CODE #ifndef SMTP_H #define SMTP_H #include <QThread> #include <QTcpSocket> class Smtp : public QThread { Q_OBJECT friend class QScopedPointerDeleter<Smtp>; private: enum SmtpState{ Init, Hello, Login, Password, From, Rcpt, Data, Body, Quit, Close }m_state; QString m_body; bool m_status; QString m_error_message; QTcpSocket *m_socket; QTextStream *m_stream; QString readSocket(); void writeSocket(const QString & data); static QByteArray encode64(const QString & secure_string); protected: explicit Smtp(const QString & message); ~Smtp(); void run(); inline bool getStatus() const { return m_status; } inline QString getErrorMessage() const { return m_error_message; } public: static bool send(const QString & message, QString & error); protected slots: void onSocketData(); }; #endif // SMTP_H и немного реализации CODE bool Smtp::send(const QString &message, QString &error) { Smtp smtp(message); smtp.start(); smtp.wait(); error = smtp.getErrorMessage(); return smtp.getStatus(); } void Smtp::run() { // if SMTP server requires secure connection if (Settings::instance()->value(Settings::KeySmtpUseSsl).toBool()) { // create new SSL socket QSslSocket * socket = new QSslSocket(this); m_socket = socket; // assign socket data handler connect(m_socket, SIGNAL(readyRead()), this, SLOT(onSocketData())); // assign proxy object if needed if (Settings::instance()->value(Settings::KeyUseProxy).toBool()) { QNetworkProxy proxy(QNetworkProxy::HttpProxy, Settings::instance()->value(Settings::KeyProxyHost).toString(), Settings::instance()->value(Settings::KeyProxyPort).toUInt(), Settings::instance()->value(Settings::KeyProxyLogin).toString(), Settings::instance()->value(Settings::KeyProxyPassword).toString()); socket->setProxy(proxy); } // connect to SMTP server over SSL socket->connectToHostEncrypted(Settings::instance()->value(Settings::KeySmtpHost).toString(), Settings::instance()->value(Settings::KeySmtpPort).toUInt()); // wait for the connection if (!socket->waitForEncrypted()) { m_status = false; m_error_message = socket->errorString(); return; } } else // SMTP server doesn't require SSL connection { // create TCP socket QTcpSocket * socket = new QTcpSocket(this); m_socket = socket; // assign socket data handler connect(m_socket, SIGNAL(readyRead()), this, SLOT(onSocketData())); // assign proxy object if needed if (Settings::instance()->value(Settings::KeyUseProxy).toBool()) { QNetworkProxy proxy(QNetworkProxy::HttpProxy, Settings::instance()->value(Settings::KeyProxyHost).toString(), Settings::instance()->value(Settings::KeyProxyPort).toUInt(), Settings::instance()->value(Settings::KeyProxyLogin).toString(), Settings::instance()->value(Settings::KeyProxyPassword).toString()); socket->setProxy(proxy); } // connect to SMTP server socket->connectToHost(Settings::instance()->value(Settings::KeySmtpHost).toString(), Settings::instance()->value(Settings::KeySmtpPort).toUInt()); // wait for connection if (!socket->waitForConnected()) { m_status = false; m_error_message = socket->errorString(); return; } } // create new text stream m_stream = new QTextStream(m_socket); // start event loop m_status = (exec() == 0); } Т.е. интересует отсылка письма с заморозкой текущего трида. Код зависает после входа в EventLoop, слот onSocketData() не вызывается, хотя при реализации в рамках одного трида все Ok. |
|
|
ViGOur |
15.6.2010, 20:34
Сообщение
#2
|
Мастер Группа: Модератор Сообщений: 3296 Регистрация: 9.10.2007 Из: Москва Пользователь №: 4 Спасибо сказали: 231 раз(а) Репутация: 40 |
Т.е. интересует отсылка письма с заморозкой текущего трида. Не совсем понял, что ты имеешь ввиду...А загвоздка думается мне в твоей функции: в ней ты создаешь объект Smtp, запускаешь поток (где он подготовливает все для нормальной работы с удаленным сервером), ждет пока он запустится, и возвращаешь статус соединения. А что потом? Выходишь из функции и объект Smtp smtp(message); вне зоны видимости, а значит он уничтожается и для него вызывается деструктор со всеми вытекающими...Для интереса можешь в этом убедиться примерно таким кодом:
|
|
|
Текстовая версия | Сейчас: 25.4.2024, 2:57 |