SMTP обеспечивает двухстороннюю связь между агентами передачи почты (МТА), клиентом и сервером. Клиенты шлют команды серверу, а серверы отвечают клиентам. Однако SMTP оговаривает последовательность SMTP-команд. Лучший способ понять это — взглянуть на образец почтовой транзакции. Следующий пример (он взят целиком из RFC 821) демонстрирует типичную почтовую транзакцию. В примере фигурирует мистер Smith (на компьютере usc.edu), посылающий сообщения мистерам Jones, Green и Brown (на компьютере mit.edu). Агент передачи почты хоста mit.edu принимает почту для мистеров Jones и Brown, однако не знает, где расположен почтовый ящик мистера Green.
Для целей дальнейшего повествования каждой строке присвоен номер и обозначено, кому она принадлежит — передатчику или приемнику. Текст справа от слов «RECEIVER» или «SENDER» содержит действительно передаваемые данные. Трехзначные цифровые комбинации в начале передаваемых строк обозначают коды ответа (их значение объясняется позже). Ответ SMTP похож на сообщения-подтверждения о доставке, поскольку появляется лишь в том случае, когда приемник получил данные.
1. RECEIVER: 220 mit.edu Simple Mail Transfer Service Ready
2. SENDER: HELO usc.edu
3. RECEIVER: 250 mit.edu
4. SENDER: MAIL FROM:<Smith@usc.edu>
5. RECEIVER: 250 OK
6. SENDER: RCPT TO:<Jones@mit.edu>
7. RECEIVER: 250 OK
8. SENDER: RCPT TO:<Green@mit.edu>
9. RECEIVER: 550 No such user here
10. SENDER: RCPT TO:<Brown@mit.edu>
11. RECEIVER: 250 OK
12. SENDER: DATA
13. RECEIVER: 354 Start mail input; end with <CRLF>.<CRLF>
14. SENDER: , Blah blah blah…
15. SENDER: …etc. etc. etc.
16. SENDER: .
17. RECEIVER: 250 OK
18. SENDER: QUIT
19. RECEIVER: 221 mit.edu Service closing transmission channel
Как видно из строки 1, когда SMTP-клиент устанавливает TCP-соединение с портом протокола 25, SMTP-сервер отвечает кодом 220. Это означает, что соединение успешно установлено:
1. RECEIVER: 220 mit.edu Simple Mail Transfer Service Ready
После того, как МТА компьютеров mit.edu и usc.edu установили соединение и обменялись приветствием, первой командой, согласно спецификации, должна быть команда HELO. Как указано в строке 2, SMTP-клиент передает HELO, указывая имя своего компьютера в качестве аргумента. Другими словами, он сообщает: «Привет, я — usc.edu». Команда HELO употребляется с аргументом, как показано ниже:
2. SENDER: HELO usc.edu
В ответ на HELO приемник выдает код 250, сообщая передатчику о том, что команда принята и обработана:
3. RECEIVER: 250 mit.edu
После установления TCP-соединения и идентификации (при помощи HELO) SMTP-клиент приступает к почтовой транзакции. Для начала он выполняет одну из следующих команд: MAIL, SEND, SOML или SAML. В нашем примере использована команда MAIL:
4. SENDER: MAIL FROM:<Smith@usc.edu>
Все четыре команды: MAIL, SEND, SOML и SAML имеют одинаковый синтаксис:
MAIL <пробел> FROM:<reverse-path> <carriage-return line-feed>
Команды SEND, SOML и SAML дополнительны и используются довольно редко.
Аргумент «обратный путь» (reverse path) указывает серверу, кому в случае ошибки отослать соответствующее сообщение. Мы еще рассмотрим его подробнее. На данный момент для нас важно, что в аргументе содержится адрес источника сообщения (в нашем случае, Smith@usc.edu). После того, как сервер выдал код ответа 250 (строка 5), согласившись обработать сообщение от Smith@usc.edu, необходимо указать получателя сообщения. Это делается при помощи команды RCPT. Команда RCPT имеет аргумент — имя получателя. На одну команду приходится только одно имя, поэтому, если получателей несколько, команда RCPT выдается несколько раз. В нашем примере команды RCPT выполняются в строках 6, 8 и 10. Синтаксис RCPT похож на синтаксис команды MAIL:
RCPT <пробел> TO:<forward-path> <CRLF>
Однако в отличие от MAIL, аргумент RCPT начинается со слова «ТО:». Содержимое аргумента — путь передачи сообщения (forward path), а не обратный путь. На данный момент для нас важно, что в пути передачи сообщения указано имя почтового ящика получателя. Выдав команду RCPT, МТА-клиент ожидает получить ответ с кодом 250. Однако в ответ на восьмую строку
8. SENDER: RCPT ТО:<Green@mit.edu>
сервер отвечает кодом 550:
9. RECEIVER: 550 No such user here
Код ответа 550 означает, что МТА не в состоянии выполнить запрос клиента, поскольку не знает, как доставить почту указанному пользователю. То есть скорее всего у мистера по фамилии Green нет почтового ящика (Green@mit.edu) на этом компьютере. В протоколе SMTP сказано, что сервер обязан информировать клиента об отсутствии почтового ящика получателя сообщения. Однако в спецификации SMTP ничего не говорится о том, как клиент должен реагировать на это сообщение.
После того, как посланы все команды RCPT, клиент начинает передачу данных при помощи команды DATA. В строке 12 показано, как МТА-клиент (передатчик) высылает команду DATA, в строке 13 — как сервер отвечает кодом 354. Этот код означает, что передача данных разрешена и должна заканчиваться комбинацией CRLF-точка-CRLF (новой строкой, содержащей только точку).
12. SENDER: DATA
13. RECEIVER: 354 Start mail input; end with <CRLF>.<CRLF>
После того, как получен код 354, клиент может начать передачу данных. МТА-сервер, в свою очередь, помещает принятые данные в очереди входящих сообщений. Сервер не высылает никаких ответов до тех пор, пока не получит комбинацию CRLF-точка-CRLF от клиента, означающую конец передачи данных. Как показано в строках 16 и 17, в ответ на полученную комбинацию CRLF-точка-CRLF, сервер выдает код 250. Как мы уже говорили, код ответа 250 означает успешное окончание операции:
16. SENDER:
17. RECEIVER: 250 OK
Для того чтобы закончить почтовую транзакцию, клиент, по правилам SMTP, обязан послать команду QUIT. Сервер, в свою очередь, отвечает кодом 221. Этот код подтверждает клиенту, что соединение будет закрыто, после чего соединение действительно закрывается:
18. SENDER: QUIT
19. RECEIVER: 221 mit.edu Service closing transmission channel
В любой момент во время транзакции клиент может использовать команды NOOP, HELP, EXPN и VRFY. В ответ на каждую команду сервер высылает клиенту определенную информацию. Конечно, в зависимости от ответа клиент может предпринять определенные действия, однако спецификация SMTP ничего не говорит по этому поводу. Например, клиент-МТА может передать команду VRFY для того, чтобы убедиться, что имя пользователя действительно. Если сервер ответит, что данного имени не существует, клиент МТА может не передавать почту для этого пользователя. В спецификации SMTP, однако, на этот счет нет никаких указаний — клиент может ничего не делать в ответ на команду VRFY. МТА-клиент может ничего не делать также в ответ на команды NOOP, HELP и EXPN — ответственность целиком лежит на разработчике конкретной реализации МТА.
Таблица 3.11
Коды ответа SMTP и их значение
Код |
Значение |
211 |
Ответ о состоянии системы или помощь |
214 |
Сообщение-подсказка (помощь) |
220 |
<имя_домена> служба готова к работе |
221 |
<имя_домена> служба закрывает канал связи |
250 |
Запрошенное действие почтовой транзакции успешно завершилось |
251 |
Данный адресат не является местным; сообщение будет передано по маршруту <forward-path> |
354 |
Начинай передачу сообщения. Сообщение заканчивается комбинацией CRLF-точка-CRLF |
421 |
<имя_домена> служба недоступна; соединение закрывается |
450 |
Запрошенная команда почтовой транзакции не выполнена, так как почтовый ящик недоступен |
451 |
Запрошенная команда не выполнена; произошла локальная ошибка при обработке сообщения |
452 |
Запрошенная команда не выполнена; системе не хватило ресурсов |
500 |
Синтаксическая ошибка в тексте команды; команда не опознана |
501 |
Синтаксическая ошибка в аргументах или параметрах команды |
502 |
Данная команда не реализована |
503 |
Неверная последовательность команд |
504 |
У данной команды не может быть аргументов |
550 |
Запрошенная команда не выполнена, так как почтовый ящик недоступен |
551 |
Данный адресат не является местным; попробуйте передать сообщение по маршруту <forward-path> |
552 |
Запрошенная команда почтовой транзакции прервана; дисковое пространство, доступное системе, переполнилось |
553 |
Запрошенная команда не выполнена; указано недопустимое имя почтового ящика |
554 |
Транзакция не выполнена |