Програмування на c і ​​з

Теорія СМТП пртокола.
Іноді найлегший спосіб посилати повідомлення полягає в тому, щоб
передати його поштового сервера самостійно. В обхід MFC і інших
наворочених класів і фунций це зробити трохи легше коли НЕ
потрібна гнучкість додатки саме в плані мульти-документного
програмування.

У цій статті я покажу наскільки легко використовувати SMTP протокол,
щоб послати email.

Послідовність подій для посилки SMTP повідомлень:
- Говоріть привіт СМТП-сервера.
- Повідомте СМТП-сервера хто має отримати повідомлення.
- Повідомте СМТП-серверу від кого дане повідомлення.
- Повідомте СМТП-серверу повідомлення.
- Говоріть до побачення СМТП-сервера.

Ви можете спілкуватися з СМТП-сервером, використовуючи команди
HELO, MAIL, RCPT, DATA, і QUIT. Відповіді СМТП-сервера складаються
з числового відповіді з трьома цифрами, супроводжуваного відповідно до
людським - легким для читання повідомленням відповіді СМТП-сервера. якщо
числова відповідь - менше ніж 400, СМТП-сервер не зіткнувся з жодними
проблемами при обслуговуванні запиту. Якщо числова відповідь більший ніж 400,
СМТП-сервер сталкнулся з проблемами, для вирішення яких треба
приймати будь-яке рішення.

Нижче показаний приклад сесії з СМТП-сервером.
Зв'язок починається, з команди HELO. Це повідомляє СМТП-сервера,
що я буду використовувати SMTP мову (хоча доступна новіша поліпшена
версія мови СМТП-сервера ESMTP). Щоб активізувати ESMTP,
Ви можете начаста з команди EHLO замість HELO.) Наступним кроком я повинен
повідомити СМТП-сервера відправника пошти, потім одержувача,
потім саме повідомлення, потім закрити зв'язок.

клієнт надсилає запит: HELO somehost.somedomain.com
СМТП сервер відповідає: 250 OK

клієнт надсилає запит: MAIL FROM:
СМТП сервер відповідає: 250 OK

клієнт надсилає запит: RCPT TO:
СМТП сервер відповідає. 250 OK

клієнт надсилає запит: RCPT TO:
СМТП сервер відповідає. 550 No such user here

клієнт надсилає запит: RCPT TO:
СМТП сервер відповідає. 250 OK

клієнт надсилає запит: DATA
СМТП сервер відповідає. 354 Start mail input; end with .

клієнт надсилає запит: All I want for Christmas.
клієнт надсилає запит. etc. etc. etc.
клієнт надсилає запит: .
СМТП сервер відповідає. 250 OK

Всі команди супроводжуються відповідями від СМТП-сервера.
ЗВЕРНЕТЕСЯ до RFC-821 для детального пояснення структур відповіді.

HELO зазвичай поcилается в лінію окремо. Це пізнає відправника
і повідомляє СМТП-серверу, що настають команди - команди SMTP,
НЕ ESMTP. Зверніть увагу в слові HELO одна буква 'L'

MAIL FROM: оголошує нове повідомлення пошти, і може
використовуватися всередині існуючого повідомлення, щоб показати
додаток до листа.

RCPT TO: визначає всіх одержувачів повідомлення.

DATA поcилается в лінію окремо. Після того, як Ви посилаєте команду
DATA, СМТП-сервера пошле назад код 354, `вводите пошту і
завершите повідомлення "." з новою лінії`.
Після читання цього початкового відповіді,
Ви можете починати фактичне повідомлення.
Однак, Ви не можете отримати іншу відповідь від СМТП-сервера, поки
Ви не закінчили секцію даних точкою (.) На окремій лінії.
У межах секції DATA, використовуйте наступні підзаголовки,
щоб форматувати повідомлення: FROM. TO. CC. BCC. DATE. and SUBJECT.

QUIT має на увазі те що, СМТП-сервер повинен послати "250 ОК" у відповідь,
потім закрити канал передачі. Ваша програма клієнта не повинна
обривати зв'язок, поки це не отримує "250 ОК" відповідь.

RSET (Скидання Сесії) повторно встановлює поточне повідомлення, і очищає
всього відправника, одержувача, дані, і державні столи.

HELP пояснює використання команди в людській - удобочитаемой формі.

NOOP (Ніякого Дії) не робить нічого іншого крім повернення "250 ОК" відповіді.

інтерпретація Відповідей
Після з'єднання з обслуговуванням (службою) SMTP, очікуйте "220" відповіді
від СМТП-сервера. Після цього, очікуйте відповідь для кожної команди,
надісланій СМТП-сервера. Кожна відповідь знаходиться в форматі трьох
числових цифр, за якими слід або пробіл або дефіс, після якого
йде відповідне людське - легкий для читання текстове повідомлення для
даного коду. Код з трьома цифрами містить всю інформацію, необхідну
для закодованої обробки відповіді. Як попередньо згадано,
код, який є менше ніж 400, вказує на успіх запиту,
і кодекс більше ніж 400 вказує що виникли проблеми.

Відповіді - отформатірованни наступним чином:
XYZ <пробел или дефис> Повідомлення

X має значення хороший, поганий або неповний відповідь, і може мати наступні значення:

'1': позитивний попередній відповідь (що не використовується взагалі)
'2': позитивну відповідь завершення
'3': позитивний проміжну відповідь
'4': перехідний негативну відповідь завершення
'5': постійний негативну відповідь завершення

Дефіс вказує, що відповідь - частина відповіді на багато рядковий запит.
Пропуск вказує, що відповідь - відповідь на останній рядок запиту.
Повідомлення тексту призначене для інформаційних цілей тільки,
і може ігноруватися вашим оброблювачем відповіді.

Створення програми отрпавкі пошти.
При створенні нового проекту вибираємо що це буде MFC AppWizard (exe)
і називатися він буде smtp. Вибираємо що це Dialog Based додаток, в
наступному вікні ставимо галочку підтвердження використання Windows Socket.
І далі тиснемо Next> до упору. Відкриваємо поле редагування діалогу і добиваємося
приблизно такого твору мистецтва.

* Двічі клацаємо по кнопці Send Mail і пишемо наступний текст

// визначаємо MySocket CSocket; в секції глобальних змінних

void CMy1again1Dlg :: OnButton1 ()
<
// TODO: Add your control notification handler code here

char responce [1 024];
int res_len;
char CRLF [2]; CRLF [0] = 10; CRLF [1] = 13;
// кожна команда для СМТП сервера повинна
// закінчуватися тобто поспіль йдуть 10 і 13

char * host = new char [m_host.LineLength () + 1];
// виділяємо місце в пам'яті для змінної Хоста
m_host.GetLine (0, host, m_host.LineLength ());
// записуємо в буфер Хост вміст ЕдітБокса Host
host [m_host.LineLength ()] = 0;
// Хост повинен бути ASCIIZ рядком тому
// дописуємо в кінець нуль

char * recipient = new char [m_recipient.LineLength ()];
// виділяємо місце в пам'яті для змінної "КОМУ"
m_recipient.GetLine (0, recipient, m_recipient.LineLength ());
// записуємо в буфер "КОМУ" вміст ЕдітБокса
// Recipient

char * from = new char [m_from.LineLength ()];
// виділяємо місце в пам'яті для змінної "ВІД КОГО"
m_from.GetLine (0, from, m_from.LineLength ());
// записуємо в буфер "ВІД КОГО" вміст ЕдітБокса
// From

if (! MySocket.Create ()) MessageBox ( "error creating socket", "", MB_OK);
// Створюємо сокет
if (! MySocket.Connect (host, 25)) MessageBox ( "error connect to socket", "", MB_OK);
// Намагаємося пріконектіться до поштового сервера введеному в поле Хост
else <
res_len = MySocket.Receive (responce, sizeof (responce));
// приймаємо відповідь від СМТП сервера.
responce [res_len] = 0;
m_log.ReplaceSel (responce);
// виводимо відповідь у вікно логів
>

MySocket.Send ( "HELO", 5);
MySocket.Send (host, m_host.LineLength ());
MySocket.Send (CRLF, 2);
// посилаємо команду "HELO someposthost.somedomain "
res_len = MySocket.Receive (responce, sizeof (responce));
// приймаємо відповідь від СМТП сервера.
responce [res_len] = 0;
m_log.ReplaceSel (responce);
// виводимо відповідь у вікно логів

MySocket.Send ( "MAIL FROM: <",12);
MySocket.Send (from, m_from.LineLength ());
MySocket.Send ( ">", 1);
MySocket.Send (CRLF, 2);
// посилаємо команду "MAIL FROM: "
res_len = MySocket.Receive (responce, sizeof (responce));
// приймаємо відповідь від СМТП сервера.
responce [res_len] = 0;
m_log.ReplaceSel (responce);
// виводимо відповідь у вікно логів

MySocket.Send ( "RCPT TO: <",10);
MySocket.Send (recipient, m_recipient.LineLength ());
MySocket.Send ( ">", 1);
MySocket.Send (CRLF, 2);
// посилаємо команду "RCPT TO: "
res_len = MySocket.Receive (responce, sizeof (responce));
// приймаємо відповідь від СМТП сервера.
responce [res_len] = 0;
m_log.ReplaceSel (responce);
// виводимо відповідь у вікно логів

MySocket.Send ( "DATA \ n", 5);
// посилаємо команду "DATA "
res_len = MySocket.Receive (responce, sizeof (responce));
// приймаємо відповідь від СМТП сервера.
responce [res_len] = 0;
m_log.ReplaceSel (responce);
// виводимо відповідь у вікно логів

// ------------------------------------------------ -------------
// тут йде блок посилає тіло повідомлення.
int y = m_body.GetLineCount ();
// беремо кількість рядків введеного тексту
for (int i = 0; i

int l_lenght = m_body.LineLength (m_body.LineIndex (i));
// обчислюємо кількість сиволов в поточному рядку
// і якщо рядок не порожня то
if (l_lenght! = 0)<
char * curent_line = new char [l_lenght + 1];
// створюємо тимчасовий буфер
m_body.GetLine (i, curent_line, l_lenght);
// записуємо в тимчасовий буфер черговий рядок
curent_line [l_lenght] = 10;

MySocket.Send (curent_line, l_lenght + 1);
// посилаємо сервера черговий рядок

delete curent_line;
// видаляємо тимчасовий буфер
>
else
// якщо рядок порожня посилаємо сервера новий рядок

MySocket.Send ( ".", 1); MySocket.Send (CRLF, 2);
// як і положенно кінець даних повинен позначатися
// точкою і з нового рядка.
res_len = MySocket.Receive (responce, sizeof (responce));
// приймаємо відповідь від СМТП сервера.
responce [res_len] = 0;
m_log.ReplaceSel (responce);
// виводимо відповідь у вікно логів

MySocket.Send ( "QUIT \ n", 5);
// посилаємо команду виходу із з'єднання.
MySocket.Close ();
// закриваємо сокет

delete host;
delete recipient;
delete from;
// видаляємо тимчасові змінні
>

* Двічі клацаємо по кнопці Quit і пишемо наступний текст

void CServerDlg :: OnCancel ()
<
// TODO: Add extra cleanup here
MySocket.Close (); // Закриваємо сокет
CDialog :: OnCancel (); // закриваючи програму
>

Замість висновку.
* Ось власне і все, тут наведені тільки концепції реалізації
клієнта СМТП сервера. Далі вибераєте самі підходить це Вам чи ні.
Обов'язково подивіться опису для всіх використовуваних тут функцій.

<<ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ

Схожі статті