Название: Отправка сообщений по протоколу SMTP Отправлено: merke от Сентябрь 08, 2010, 17:11 Несколько раз требовалось в программах реализовать отправку писем именно по протоколу SMTP, блуждал по форумам и ни как не мог найти существенной - простой реализации на кутях. Выбив маленько времени в графике решил написать свой класс, дабы в следующий раз не усложнять себе жизнь.
Выкладываю исходники класса. В приложении будет релиз консольного приложения. smtp.h Код: #ifndef SMTP_H smtp.cpp Код: #include <smtp.h> Пример простой отправки: Код: smtp *mail = new smtp("smtp.mail.ru", 25); Код может быть и не универсален! Жду критику=) Поменять расширение вложения на .rar Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Amigo_sa от Сентябрь 08, 2010, 17:59 очень полезный для меня класс, спасибо!
Пожелание, не могли бы вы выложить файл проекта, а то многие mingwm не имеют =). Хотя я и так код ручками копировал) Название: Re: Отправка сообщений по протоколу SMTP Отправлено: merke от Сентябрь 08, 2010, 18:03 Вот вам сорсы, во вложении изменить расширение на .rar
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 08, 2010, 19:02 Код
Этож песец так писать.. Не удержался ) Рекомендую глянуть в сторону функции QString::arg Код
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: merke от Сентябрь 08, 2010, 19:33 окей, учту! Да блин несколько лет писал на VB и всё остаются привычки=)
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 08, 2010, 19:45 Видно что недавно на сях )
Вижу утечки: Код: smtp::smtp(QString host, quint16 port) Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Авварон от Сентябрь 08, 2010, 20:02 есть некий проект, но я не помню как зовется что-то типа qmp или qsmtp. Короче набор классов для работы с почтой, включая самописный сервак на Qt, реализацию pop, imap, smtp
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Amigo_sa от Сентябрь 08, 2010, 21:50 Видно что недавно на сях ) Конечно это потенциальная ошибка, но если по логике программы класс smtp живет вместе с процессом всегда, то не страшно.Вижу утечки: Код: smtp::smtp(QString host, quint16 port) Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 08, 2010, 23:39 Цитировать Конечно это потенциальная ошибка, но если по логике программы класс smtp живет вместе с процессом всегда, то не страшно. Только потом, когда смотришь как кутэ течет, да как визуальные стили текут (qtcurve да oxygen), да остальные системные либы... переходы по не инициализированным переменным пачками... не по себе как-то. Они видимо тоже так думают :) Название: Re: Отправка сообщений по протоколу SMTP Отправлено: vadim303 от Сентябрь 09, 2010, 09:43 Видно что недавно на сях ) Конечно это потенциальная ошибка, но если по логике программы класс smtp живет вместе с процессом всегда, то не страшно.Вижу утечки: Код: smtp::smtp(QString host, quint16 port) Edit: Ну и чтобы ваш класс было так же удобно использовать, сделайте конструктор как полагается: в smtp.h: Код: smtp(QString host, quint16 port, QObject *parent = 0); Код: smtp::smtp(QString host, quint16 port, QObject *parent) : QObject(parent) Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Авварон от Сентябрь 09, 2010, 13:55 navrocky
а чем вы меряли утечки, простите? лично я их в Qt не нашел (вру, нашел 1). Возможно ваша тулза таки неправильно показывает? Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 09, 2010, 16:15 Цитировать а чем вы меряли утечки, простите? лично я их в Qt не нашел (вру, нашел 1). Возможно ваша тулза таки неправильно показывает? Под линуксом - valgrind. Обычно он не ошибается. Часто кажется что он врет, но после долгих раскопок все-таки находишь )Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Авварон от Сентябрь 09, 2010, 16:31 он врет:)
он тупит из-за статик переменных, насколько я знаю. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: varkon от Сентябрь 09, 2010, 17:47 он врет:) а есть принципиальная разница - врет он или нет? Или в Qt реализован сборщик мусора? Оба ответа - нет.он тупит из-за статик переменных, насколько я знаю. Выделенные ресурсы надо освобождать, либо использовать "умные указатели". Подход - "но если по логике программы ...." - был, есть и будет основным источником ошибок в приложениях. З.Ы. Это относится к данному конкретному коду, а не к высказыванию о массовости memory licks от navrocky. Хотя в целом не так уж он и неправ. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Авварон от Сентябрь 09, 2010, 17:57 я про Qt веду речь:) а в данном коде да, утечка и никакие "логики" ее не оправдывают
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 10, 2010, 09:24 З.Ы. Это относится к данному конкретному коду, а не к высказыванию о массовости memory licks от navrocky. Хотя в целом не так уж он и неправ. Почему же не прав :) У меня большой проект, все свои ошибки работы с памятью я полечил (на мой код valgrind не ругается и все ошибки которые я нашел были по существу), однако у меня есть большой файл подавлений ошибок системных библиотек, и Qt в их числе... Например, первое что попалось (qt 4.6.2): Код: src/gui/widgets/qdockarealayout.cpp:1936 И так во многих системных библиотеках, в бусте, в ld.so и так далее. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Авварон от Сентябрь 12, 2010, 14:49 тут передается виджет как параметр в конструкторе и ятп что док виджет айтем будет удален при удалении виджета
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 13, 2010, 10:22 тут передается виджет как параметр в конструкторе и ятп что док виджет айтем будет удален при удалении виджета QDockWidgetItem -> QWidgetItem -> QLayoutItem Не наследник QObject, автоматическое удаление не работает. Просмотри их конструкторы, там нигде нет регистрации у widget.. И оно конечно течет. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Авварон от Сентябрь 13, 2010, 10:49 то, что не используется механизм родства куобжектов, не означает, что нет удаления руками. Настолько тупых ошибок в qt нет
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: SABROG от Сентябрь 13, 2010, 13:23 QMF (http://qt.gitorious.org/qt-labs/messagingframework) пробовали?
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: ритт от Сентябрь 13, 2010, 15:19 Код
Этож песец так писать.. Не удержался ) Рекомендую глянуть в сторону функции QString::arg Код
ой, не надо советовать херню :) ваше QString( "From: %1\nTo: %2\nSubject: %3\n\n%4\n" ).arg(p_mail_From).arg(p_mail_to).arg(subject).arg(body); в разы медленнее перегруженного += а вот QString::fromLatin1() я бы заменил на QLatin1String() - для наглядности... Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 14, 2010, 11:36 Цитировать ой, не надо советовать херню :) Это не "херня". Если код не критичен к скорости исполнения (в данном случае это так), то format предпочтительнее, так как более наглядно и компактно выглядит, позволяет отформатировать вставляемые значения, поддается переводу. Так что не надо ля-ля... >:( ЗЫЖ QLatinXXX здесь в любом случае лишний, т.к. в его коде нет специфичных для Latin-1 символов. И вообще в исходники должны быть в UTF-8 и строки грузиться через tr() и QString::fromUtf8 Название: Re: Отправка сообщений по протоколу SMTP Отправлено: ufna от Сентябрь 14, 2010, 11:43 Так, а реально ::fromLatin1(..) быстрее чем .arg() пихать? Сильная разница?
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 14, 2010, 12:19 Цитировать Так, а реально ::fromLatin1(..) быстрее чем .arg() пихать? Сильная разница? Я вот даже отвлекся и написал тест: Код
Собирал релиз с оптимизаций -O2. Результат тестирования: Код: 2010-Sep-14 13:14:04.882129 D: 72 TH:0 (dbg )1 syslog: Thread #0 with id=0x83358e0 Выводы делайте сами ;) Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Kolobok от Сентябрь 14, 2010, 12:52 Не совсем корректно. Попробуй добавить в тест изменяемый стринг. Например QString::number(i)
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 14, 2010, 13:10 Код
Код: 2010-Sep-14 14:08:07.448952 D: 71 TH:0 (dbg )1 syslog: Thread #0 with id=0x8718bb8 3212 ms против 2903 ms. Опять же победа за .arg().. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Авварон от Сентябрь 14, 2010, 13:49 проверьте на длинных строках - чтобы было много переалокаций
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Kolobok от Сентябрь 14, 2010, 13:53 У меня другие результаты
Код: int cnt = 1000000; Цитировать Started QString .arg() function. Total iterations 1000000 Finished arg() 8641 Started QString PLUS operator. Total iterations 1000000 Finished plus 6665 Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 14, 2010, 14:55 У меня другие результаты Странно. Какая система? У меня AthlonX4, OpenSuse11.2 32bit, gcc 4.4.1, Qt 4.6.2. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Kolobok от Сентябрь 14, 2010, 15:21 Intel Core2 Duo, Win7, gcc 4.4.0, Qt 4.7
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: ритт от Сентябрь 14, 2010, 19:51 раз уж такие пляски,
QString::arg() - это поиск с заменой. причём, вставляемая подстрока обычно длиннее заменямой -> многократные выделения и копирования области памяти... Цитировать There are three ways you can access this improved method of string construction. The straightforward way is to include QStringBuilder wherever you want to use it, and use the '%' operator instead of '+' when concatenating strings: #include <QStringBuilder> QString hello("hello"); QStringRef el(&hello, 2, 3); QLatin1String world("world"); QString message = hello % el % world % QChar('!'); A more global approach is to include this define: #define QT_USE_FAST_CONCATENATION and use '%' instead of '+' for string concatenation everywhere. The third approach, which is the most convenient but not entirely source compatible, is to include two defines: #define QT_USE_FAST_CONCATENATION #define QT_USE_FAST_OPERATOR_PLUS and the '+' will automatically be performed as the QStringBuilder '%' everywhere. iirc, в 4.7 QT_USE_FAST_CONCATENATION объявлен по умолчанию, что уже даёт ощутимую оптимизацию; объявлением QT_USE_FAST_OPERATOR_PLUS включаем эту оптимизацию повсеместно для кода QString() + QString(). т.о. получаем всего одно выделение памяти и несколько копирований... что быстрее? зы. не бывает некритичного к производительности кода. нужно просто писать хороший код) к примеру, если вы знаете, что передача параметра по ссылке быстрее, чем копирующий конструктор, вы же будете в функциях использовать ссылки, независимо от того, является ли код критичным к производительности или нет, верно?) Название: Re: Отправка сообщений по протоколу SMTP Отправлено: navrocky от Сентябрь 15, 2010, 00:04 Но у .arg есть неоспоримые преимущества - наглядность и возможность перевода. Я его использую повсеместно, и только там где жмет производительность уже заморачиваюсь.
Потом, оптимизация суммирования строк - это новая фича начиная с 4.6 (я об этом и не знал даже). До этого было все уныло. И потом никто не мешает также соптимизировать функции форматирования также через билдер, я подозреваю что в одной из следующих версий и до нее доберутся. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: majatu от Апрель 28, 2011, 11:19 как-то не по теме разговор, лучше расскажите, как вложение отправить
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: CuteBunny от Апрель 29, 2011, 07:39 Код
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: daimon от Июнь 15, 2011, 17:19 Вот вам сорсы, во вложении изменить расширение на .rar при создании rar есть выбор в zipНазвание: Re: Отправка сообщений по протоколу SMTP Отправлено: asrael от Сентябрь 11, 2012, 21:32 Отличная вещь! Только почему-то меняет в теме письма "_" на " ". Изменение кодировки дело не меняет..
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: PavelVX от Октябрь 18, 2012, 06:20 Подскажите пожалуйста: а можно как-то отправлять почту через почтового клиента по умолчанию? Для всех подобно этому коду нужно знать, адруса, smtp сервера. Но есть почтовый клиент уже настроенный. Можно ли через него отправлять письма с вложеним?
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: virtual_root от Ноябрь 22, 2012, 12:56 спасибо за код, он прекрасно работает!
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Hirurg от Август 28, 2018, 12:02 Здравствуйте! К сожалению код уже не так прекрасно работает и серверы mail.ru отвечают "500 AUTH available only with SSL or TLS\r\n"
Подскажите пожалуйста, можно ли как-то модифицировать этот код с учётом изменения политики mail.ru относительно шифрования, и если да, то как? Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Apktyc от Август 28, 2018, 12:37 Здравствуйте! К сожалению код уже не так прекрасно работает и серверы mail.ru отвечают "500 AUTH available only with SSL or TLS\r\n" Начать использовать QSslSocket для установки защищенного соединения. На 465 порте (обычно implicitTLS) должно хватить и этого. Для 587 порта (обычно explicitTLS) потребуется реализация ssl рукопожатия (STARTTLS и т.д.).Подскажите пожалуйста, можно ли как-то модифицировать этот код с учётом изменения политики mail.ru относительно шифрования, и если да, то как? Не забываем подложить приложению библиотеки libeay32.dll, ssleay32.dll (проживают Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Hirurg от Август 28, 2018, 12:49 Начать использовать QSslSocket для установки защищенного соединения. На 465 порте (обычно implicitTLS) должно хватить и этого. Для 587 порта (обычно explicitTLS) потребуется реализация ssl рукопожатия (STARTTLS и т.д.). Спасибо за ответ! Продолжил копаться на форуме, прочитал про QSslSocket и решение пришло само собой ;)Не забываем подложить приложению библиотеки libeay32.dll, ssleay32.dll (проживают С библиотеками libeay32.dll, ssleay32.dll немножко пришлось помучаться, мне помогло следующее решение: https://forum.qt.io/topic/91777/qsslsocket-cannot-call-unresolved-function-sslv23_client_method (https://forum.qt.io/topic/91777/qsslsocket-cannot-call-unresolved-function-sslv23_client_method) Если в двух словах, скачал с сайта http://slproweb.com/products/Win32OpenSSL.html (http://slproweb.com/products/Win32OpenSSL.html) инсталляцию Win32_OpenSSL_v1.0.2p.exe, и уже из неё взял нужные dll. С теми, которые на дне океана, не заработало Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Hirurg от Август 28, 2018, 18:03 Всё-таки надо прояснить ещё кое-что, а точнее кодировку темы сообщения.
Исходники хранятся в Utf-8 и выглядят так: Цитировать QString subject = QString::fromLocal8Bit("Тема письма"); По итогу текст сообщения отображается в полученном письме корректно, а тема выглядит какQString body = QString::fromLocal8Bit("Текст сообщения"); Цитировать Тема Ð¿Ð¸Ñ ÑŒÐ¼Ð° Что делать, как правильно преобразовать строку для темы письма?Название: Re: Отправка сообщений по протоколу SMTP Отправлено: sergek от Август 28, 2018, 20:31 Знакомая проблема. Я использую библиотеку SmtpClient for Qt (Tőkés Attila), так там для того, чтобы избежать этих кракозябр, нужно отдельно задавать кодировку темы письма.
Код В самой библиотеке строка преобразования темы выглядит так (mimemessage.cpp): Код Ну и используется кодировка QuotedPrintable::encode (quotedprintable.cpp). Посмотрите исходники, думаю, разберетесь (я не вникал)) Кстати, проблема вылезала только на смартфонах, в mail.ru все было хорошо. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Apktyc от Август 28, 2018, 20:44 Надо смотреть заголовок письма, какая кодировка там.
utf-8?Q? - это quoted-printable; utf-8?B? - base64. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: ssoft от Август 28, 2018, 21:16 Исходники хранятся в Utf-8 и выглядят так: Цитировать QString subject = QString::fromLocal8Bit("Тема письма"); QString body = QString::fromLocal8Bit("Текст сообщения"); Если исходники в utf-8, то должно быть Код
Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Hirurg от Август 29, 2018, 10:15 Если исходники в utf-8, то должно быть Вот так вообще ничего не читается, в заголовке вижу ���� ������QString subject = QString::fromUtf8("Тема письма"); QString body = QString::fromUtf8("Текст сообщения"); Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Apktyc от Август 29, 2018, 10:29 Исходники не читай@сразу отвечай
Для варианта исходники в utf-8, в письме base64 делаю так: Код
Никаких лишних преобразований не делается. Название: Re: Отправка сообщений по протоколу SMTP Отправлено: Hirurg от Август 29, 2018, 16:35 Никаких лишних преобразований не делается. Спасибо огромное, ваш ответ подтолкнул к решению проблемы! Преобразовывать к base64 я уже пробовал, а вот как прописать в явном виде кодировку темы, понял только теперь.В общем, сделал вот так и всё заработало: Код ещё раз спасибо! |