crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> 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  


Цитата(CbIHOK @ 15.6.2010, 8:11) *
Т.е. интересует отсылка письма с заморозкой текущего трида.
Не совсем понял, что ты имеешь ввиду...

А загвоздка думается мне в твоей функции:
bool Smtp::send(const QString &message, QString &error)
{
    Smtp smtp(message);
    smtp.start();
    smtp.wait();
    error = smtp.getErrorMessage();
    return smtp.getStatus();
}
в ней ты создаешь объект Smtp, запускаешь поток (где он подготовливает все для нормальной работы с удаленным сервером), ждет пока он запустится, и возвращаешь статус соединения. А что потом? Выходишь из функции и объект Smtp smtp(message); вне зоны видимости, а значит он уничтожается и для него вызывается деструктор со всеми вытекающими...

Для интереса можешь в этом убедиться примерно таким кодом:
Smtp::Smtp(...)
{
   qDebug()<<"Создаем Smtp";
}
...
Smtp::~Smtp()
{
   qDebug()<<"Уничтожаем Smtp";
}
...
qDebug()<<"Отправляем данные";
Smtp::send(...)
qDebug()<<"Отправили данные";
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 18.9.2021, 17:33