Поскольку электронная почта необычно популярна, существует множество документов
на эту тему. Вместо того чтобы рассматривать все эти документы, посвященные
электронной почте, мы лучше обрисуем несколько ключевых и самых важных моментов.
После прочтения данной статьи вы узнаете ключевые моменты протокола SMTP и
будете ориентироваться в многочисленных "почтовых" RFC.
SMTP
(Simple Mail Transfer Protocol - протокол передачи почты)
используется для передачи писем на на e-mail. Использует 25 порт, по
которому посылаются команды и текст письма.
Протокол Smtp обеспечивает двух-сторонний обмен
сообщениями между локальным клиентом и удаленным сервером MTA. MTA-клиент
шлет команды MTA-серверу, а он, в свою очередь отвечает клиенту. Другими
словами, протокол SMTP требует получать ответы от приемника команд SMTP.
Обмен между клиентом и сервером, называется почтовой транзакцией (mail
transaction). Данные, передаться в формате NVT ASCII.
Кроме того, команды также передаться в формате NVT ASCII.
Они передаться в формате ключевых слов, и указывают не необходимость
выполнить ту или иную операцию.
Вот ключевые команды спецификации SMTP - RFC 821.
Команда |
Обязательна |
Описание |
HELO |
X |
Идентифицирует модуль-передатчик для
модуля-приемника (hello) |
MAIL |
X |
Начинает почтовую транзакцию, которая
завершается передачей данных в один или несколько почтовых ящиков
(mail) |
RCPT |
X |
Идентифицирует получателя почтового сообщения |
DATA |
|
Строки, следующие за этой командой,
рассматриваются получателем как данные почтового сообщения. Почтовое
сообщение заканчивается комбинацией символов CRLF-точка-CRLF. |
RSET |
|
Прерывает текущую почтовую транзакцию (reset). |
NOOP |
|
Требует от получателя не принимать ни каких
действий, а только выдавать ответ OK. Используется в основном для
тестирования. (No operation) |
QUIT |
|
Требует выдать ответ OK и закрыть текущее
соединение. |
VRFY |
|
Требует от приемника подтвердить, что ее
аргумент является действительным именем пользователя. |
SEND |
|
Начинает почтовую транзакцию, доставляющую
данные на один или несколько терминалов (а не в почтовый ящик). |
SOML |
|
Начинает транзакцию MAIL или SEND, доставляющие
данные на один или несколько терминалов или в почтовые ящики. |
SAML |
|
Начинает транзакцию MAIL или SEND, доставляющие
данные на один или несколько терминалов и в почтовые ящики. |
EXPN |
|
Команда SMTP-приемнику подтвердить,
действительно ли аргумент является адресом почтовой рассылки и если
да, вернуть адрес получателя сообщения (expand) . |
HELP |
|
Команда SMTP-приемнику вернуть сообщение-справку
о его командах. |
TURN |
|
Команда SMTP-приемнику либо сказать OK и
поменяться ролями, то есть стать SMTP-передатчиком, либо послать
сообщение-отказ и остаться в роли SMTP-приемника. |
Команды, помеченные крестиком (Х) в таблице, обязаны
присутствовать в любой реализации SMTP. Остальные команды SMTP могут быть
реализованы дополнительно. Каждая SMTP-команда должна заканчиваться либо
пробелом (если у нее есть аргумент), либо комбинацией CRLF. В описании
команд употреблялось слово "данные", а не "сообщение". Этим подчеркивалось,
что, кроме текста, SMTP позволяет передавать и двоичную информацию, например
графические или звуковые файлы. Другими словами, SMTP способен передовая
данные любого содержания.
Последовательность команд SMTP.
Текст справа от сокращений (S. - Sender, R.-Receiver)
содержит действительно передаваемые данные. Трехзначные цифровые комбинации
в начале передаваемых строк обозначают коды ответа (их значение объясняется
позже). Ответ SMTP похож на сообщение подтверждения о доставке, поскольку
появляется лишь в том случае , когда приемник получил данные.
R. 220-proxy.kirov.ru ESMTP Sendmail 8.12.6/8.12.6; Mon, 16 Dec 2002 21:00:08 +0300 (MSK)
R. 220-Use of this system for the delivery of UCE (a.k.a. SPAM), or any other
R. 220-message without the express permission of the system owner is prohibited.
R. 220 Use of this system for third party relaying is prohibited.
При установке TCP-соединения с сервером, с портом протокола 25, SMTP сервер
отвечает кодом 220. Это обозначает что соединение успешно произведено. Также
сервер выводит дополнительную информацию о данном SMTP сервере.
S. HELO ezmail.ru
После того как прошло успешное соединение с сервером и обменялись
приветствием, первой командой, согласно спецификации, должна быть команда HELO.
SMTP-клиент передает HELO, указывая имя своего компьютера в качестве аргумента.
Другими словами, он сообщает: "Привет, я - ezmail.ru".
R. 250 proxy.kirov.ru Hello mail.kirov.ru [192.89.200.58], pleased to meet you
В ответ на HELO приемник выдает код 250, сообщая передатчику о том, что
команда принята и обработана. После установления TCP-соединения и идентификации
(при помощи HELO) SMTP-клиент приступает к почтовой транзакции. Для начала он
выполняет одну из следующих команд: MAIL, SEND, SOML или SAML. В нашем примере
используется команда MAIL.
S. MAIL FROM:dimon@ezmail.ru
R. 250 2.1.0 ... Sender ok
Аргумент "обратный путь" указывает серверу, кому в случае ошибки отослать
соответствующее сообщение. В данный момент оно содержит адрес источника
сообщения (в нашем случае dimon@ezmail.ru).
S. RCPT TO:alex@ezmail.ru
Далее необходимо указать получателя сообщения. Для этого
необходимо прибегнуть к команде RCPT. Команда RCPT имеет аргумент - имя
получателя. В данном случае получателем является пользователь, имеющий почтовый
адрес alex@ezmail.ru.
На одну команду приходится только одно имя, поэтому, если
получателей несколько, команда RCPT выдается несколько раз.
R. 250 2.1.5 ... Recipient ok
В ответ на команду RCPT сервер отвечает кодом 250,
сигнализируя что данный почтовый адрес реально существует. В противном случае
сервер выдаст ошибку 550
S. DATA
После того как посланы все команды RCPT, клиент начинает
передачу данных при помощи команды DATA.
R. 354 Enter mail, end with "." on a line by itself
Сервер отвечает кодом 354, сигнализируя, что передача данных
разрешена.
S. From: dimon@ezmail.ru
Comments: This is a test
S. To: alex@ezmail.ru
S. Subject: Писмо
S. Sender: alex@ezmail.ru
S. Mime-Version: 1.0
S. Content-Type: text/plain; charset="windows-1251"
S. Date: Mon, 16 Dec 2002 21:02:16 +0300
S.
S. Письмо
S. .
Далее идет тело письма, где содержится описание входящих
данных и собственно сами данные.
R. 250 2.0.0 gBGI08oN023828 Message accepted for delivery
При успешном приеме сервером тела письма, сервер выдает код
250.
R. QUIT
S. 221 2.0.0 proxy.kirov.ru closing connection
Для того чтобы закончить почтовую транзакцию, клиент по
правилам SMTP, обязан послать команду QUIT. Сервер в свою очередь, отвечает
кодом 221. Этот код подтверждает клиенту, что соединение будет закрыто, после
чего соединение действительно закрывается.
В любой момент во время транзакции, клиент может использовать
любые команды NOOP, HELP, EXLP и VRFY. В ответ на каждую команду сервер высылает
клиенту определенную информацию.
Интересным дополнением к традиционной электронной почте
является ее расширение MIME (Multupurpose
Internet Mail Extentions, RFC-1521). MIME не требует каких-либо
переделок в почтовых серверах, это расширение определяет пять новых
полей-заголовков (расширение RFC-822):
MIME-Version: (версия MIME, в настоящее время 1.0); |
Content-Type: (тип почтового сообщения); |
Content-Transfer-Encoding: (кодирование почтового сообщения); |
Content-ID: (идентификатор почтового сообщения) |
Content-Description: (описание почтового сообщения). |
Поле заголовка Content-Transfer-Encoding использует пять
типов кодировки:
7-битовый набор (NVT ASCII, по умолчанию); |
набор печатных символов (полезен, когда только небольшая часть
символов использует восьмой бит); |
64-символьный набор Base64; |
8-битовый набор символов, включающий псевдографику с использованием
построчного представления; |
двоичная кодировка (8-битовая кодировка без разбивки на строки). |
Только первые три вида согласуются с требованиями RFC-821.
MIME позволяет снять с электронной почты привычные ограничения и предоставляет
возможность пересылать любую информацию. При этом необходимо только, чтобы и
приемник и передатчик поддерживали это расширение электронной почты. Типы и
субтипы почтового сообщения, предусмотренные в MIME.
Тип почтового сообщения |
Субтип почтового сообщения |
Описание |
text |
plain |
Неформатированный текст. |
richtext |
Текст с простым форматированием: курсив, жирный, с подчеркиванием и
т.д. |
enriched |
Упрощение, прояснение и усовершенствование richtext. |
multipart |
mixed |
Сообщение содержит несколько частей, которые обрабатываются
последовательно. |
parrallel |
Сообщение содержит несколько частей, обрабатываемых параллельно. |
digest |
Краткое содержание сообщения. |
alternative |
Сообщение содержит несколько частей с идентичным семантическим
содержимым |
message |
rfc822 |
Почтовое сообщение в стандарте RFC-822. |
patial |
Фрагмент почтового сообщения. |
external-body |
Указатель действительного текста сообщения |
application |
octet-stream |
Произвольная двоичная информация. |
postscript |
Программа PostScript |
image |
jpeg |
Формат ISO 10918. |
gif |
Формат обмена CompuServe (Graphic Interchange Format) |
audio |
basic |
Формат ISO 11172 |
Коды ответов SMTP.
Каждая цифра в коде ответа несет определенный смысл. Первая
цифра означает, было ли выполнение команды успешно (2), неуспешно (5) или еще не
закончилось (3).
Вторая цифра обозначает категорию ошибки. Например 0,
означает синтаксическую ошибку.
Каждое сообщение обозначает отдельную синтаксическую ошибку.
Поскольку строки, описывающие различные виды ошибок, разные, то и коды ответа
отличаться друг от друга. Для этих целей вводиться третья цифра.
Ниже в таблице приведены коды ответа SMTP и их значения.
211 |
System status, or system help reply |
Статус системы или Help |
214 |
Help message. [Information on how to use the receiver or the meaning
of a particular non-standard command; this reply is useful only to the
human user] |
Краткая справка |
220 |
Service ready |
SMTP-сервис готов к работе |
221 |
Service closing transmission channel |
Сервис закрыл канал передачи данных |
250 |
Requested mail action okay, completed |
Соединение установлено |
251 |
User not local; will forward to |
Пользователь не местный. Выполнить перенаправление запроса |
354 |
Start mail input; end with . |
Начать ввод почтового сообщения |
421 |
Service not available, closing transmission channel [This
may be a reply to any command if the service knows it must shut down]
|
Сервис отсутствует. Канал передачи данных закрыт |
450 |
Requested mail action not taken: mailbox unavailable [E.g., mailbox
busy] |
Нет возможности записать данные в почтовый ящик |
451 |
Requested action aborted: local error in processing |
Ошибка при обработке запроса |
452 |
Requested action not taken: insufficient system storage |
Запрос не выполнен недостаточно памяти на вычислительной установке
|
500 |
Syntax error, command unrecognized [This may include errors such as
command line too long] |
Синтаксическая ошибка - нет такой команды |
501 |
Syntax error in parameters or arguments |
Синтаксическая ошибка в аргументах команды |
502 |
Command not implemented |
Данная команда не может быть выполнена |
503 |
Bad sequence of commands |
Неправильная последовательность команд |
504 |
Command parameter not implemented |
Параметр команды не может быть использован в данном контексте |
550 |
Requested action not taken: mailbox unavailable [E.g., mailbox not
found, no access] |
Не найден соответствующий почтовый ящик |
551 |
User not local; please try |
Пользователь не найден можно попробовать отправить почту по другому
адресу |
552 |
Requested mail action aborted: exceeded storage allocation |
Превышены квоты на использование ресурсов памяти |
553 |
Requested action not taken: mailbox name not allowed [E.g., mailbox
syntax incorrect] |
Имя почтового ящика неправильное |
554 |
Transaction failed |
Обмен завершился аварийно |
211 |
System status, or system help reply |
Статус системы или Help |
214 |
Help message. [Information on how to use the receiver or the meaning
of a particular non-standard command; this reply is useful only to the
human user] |
Краткая справка |
220 |
Service ready |
SMTP-сервис готов к работе |
221 |
Service closing transmission channel |
Сервис закрыл канал передачи данных |
250 |
Requested mail action okay, completed |
Соединение установлено |
251 |
User not local; will forward to |
Пользователь не местный. Выполнить перенаправление запроса |
354 |
Start mail input; end with . |
Начать ввод почтового сообщения |
421 |
Service not available, closing transmission channel [This
may be a reply to any command if the service knows it must shut down]
|
Сервис отсутствует. Канал передачи данных закрыт |
450 |
Requested mail action not taken: mailbox unavailable [E.g., mailbox
busy] |
Нет возможности записать данные в почтовый ящик |
451 |
Requested action aborted: local error in processing |
Ошибка при обработке запроса |
452 |
Requested action not taken: insufficient system storage |
Запрос не выполнен недостаточно памяти на вычислительной установке
|
500 |
Syntax error, command unrecognized [This may include errors such as
command line too long] |
Синтаксическая ошибка - нет такой команды |
501 |
Syntax error in parameters or arguments |
Синтаксическая ошибка в аргументах команды |
Тестирование обслуживания по протоколу SMTP
Для проверки сервиса SMTP применяют программу telnet,
запущенную по порту 25:
telnet ezmail.ru 25
В этом случае система отвечает строкой приглашения протокола
SMTP, после чего можно вводить команды SMTP и проверять реакцию системы на них:
# telnet ezmail.ru 25
Trying 192.85.135.66...
Connected to ezmail.ru.
Escape character is '^]'.
220 ezmail.ru ESMTP Sendmail 8.8.5/8.8.5; Mon, 30 Jun 1997 09:45:55 GMT
help
214-This is Sendmail version 8.8.5
214-Topics:
214- HELO EHLO MAIL RCPT DATA
214- RSET NOOP QUIT HELP VRFY
214- EXPN VERB ETRN DSN
214-For more info use "HELP".
214-To report bugs in the implementation send email to
214- sendmail-bugs@sendmail.org.
214-For local information send email to Postmaster at your site.
214 End of HELP info
MAIL FROM: alex
250 alex... Sender ok
RCPT TO: alex
250 alex... Recipient ok
DATA
354 Enter mail, end with "." on a line by itself
This is a test message
.
250 JAA24836 Message accepted for delivery
quit
221 cit-u.citmgu.ru closing connection
Connection closed by foreign host.
You have new mail.
#
В приведенном здесь сеансе сначала пользователь выдал команду
help и получил список команд, которые можно использовать при взаимодействии по
протоколу SMTP. Затем пользователь выдал команду MAIL FROM: для указания адреса
отправителя почтового сообщения. После этого выдана команда RCPT TO:, и указан
адрес получателя почтового сообщения. Команда DATA открывает возможность ввода
почтового сообщения, т.е. клиент из режима командной строки переходит в режим
редактирования сообщения. Редактировать можно только в пределах одной строки
путем затирания символом забоя предварительно набитых символов. Вернуться на
строку выше нельзя. Конец режима редактирования обозначается символом "." в
первой позиции строки. После этого клиент возвращается в режим командной строки,
а сообщение отсылается. Совершенно очевидно: что за один сеанс можно отправить
несколько сообщений как одному и тому же адресату, так и разным адресатам на
одном и том же компьютере. Посылать сообщения можно через другую машину, если в
качестве адреса получателя указать что-либо подобное ниже приведенному:
alex%mail.ru@ezmail.ru
В этом случае сообщение отправляется на ezmail.ru, а затем
оно будет переправлено на mail.ru.
Работа с SMTP протоколом на Delphi.
Для работы с SMTP существует множество различных компонентов,
но одним из ведущих считается IdSMTP из пакета INDY (http://www.nevrona.com/indy/).
Данный компонент очень прост в понимании, вам не составит труда с ним
разобраться. По данной причине создатели Delphi включили пакет INDY в пакет
стандартных компонентов поставляемых с Delphi6 и Delphi7. Также хочу упоминать
пакет компонентов работы с интернетом ICS (http://overbyte.delphicenter.com/frame_index.html).
Данный пакет можно легко скачать из интернета, причем он распространяется
бесплатно и с исходным текстом.
Рассмотрим практический пример работы c SMTP на основе
компонента ICS.
Для работы с SMTP, выберитите на вкладке FPiette компонент
SmtpClient и положите его на главную форму. Далее, необходимо создать 7 кнопок и
назвать их, Connect, Helo, MainFrom, RcptTo, Data, Quit и Abort.
После этого необходимо создать 6 Edit-ов, Для ввода
параметров для SMTP соединения.
Затем начинаем писать обработчики нажатия клавиш:
- Connect:
//С каким SMTP сервером будем работать.
SmtpClient.Host := HostEdit.Text;
//Порт SMTP серера (например 25)
SmtpClient.Port := PortEdit.Text;
//Приступить к соединению с SMTP сервером
SmtpClient.Connect;
- Helo:
//Название сервера, которого будем приветствовать
SmtpClient.SignOn := SignOnEdit.Text;
//Поздороваться с сервером
SmtpClient.Helo;
- MailFrom:
//Почтовый адрес на который при возникновении ошибки сервер
вышлет уведомление о ошибке, также используется в письме, как
обратный адрес.
SmtpClient.FromName := FromEdit.Text;
SmtpClient.MailFrom;
- RcptTo
//Процедура для обработки адреса получателя
BuildRcptList;
//Информируем сервер кому мы хотим послать письмо
SmtpClient.RcptTo;
procedure TSmtpTestForm.BuildRcptList;
var
Buf : String;
I : Integer;
begin
SmtpClient.RcptName.Clear;
Buf := ToEdit.Text;
while TRUE do begin
I := Pos(';', Buf);
if I <= 0 then begin
SmtpClient.RcptName.Add(Trim(Buf));
break;
end
else begin
SmtpClient.RcptName.Add(Trim(Copy(Buf, 1, I - 1)));
Delete(Buf, 1, I);
end;
end;
end;
- Data:
//Приступаем непосредственно к передаче данных на почтовый ящик.
BuildRcptList;
SmtpClient.HdrFrom := FromEdit.Text;
SmtpClient.HdrTo := ToEdit.Text;
//Здесь определяем тему письма
SmtpClient.HdrSubject := SubjectEdit.Text;
//Если необходимо с письмом передать файл с данными то в параметр EmailFile записываем локальный путь на диске.
SmtpClient.EmailFiles := FileAttachMemo.Lines;
SmtpClient.Data;
- Quit:
//Закрываем почтовую сессию
SmtpClient.Quit;
- Abort:
//Обрываем соединение с сервером.
SmtpClient.Abort;
Более детально разобраться с данным примером вы можете, после
того как инсталлируете компонент и запустите демонстрационный проект с названием
MAILSND.DPR.
Автор: Фофанов Дмитрий
|