Приступим!
Основная задача протокола SMTP (Simple Mail Transfer Protocol) заключается в том, чтобы обеспечивать передачу электронных сообщений (почту). Для работы через протокол SMTP клиент создаёт TCP соединение с сервером через порт 25. Затем клиент и SMTP сервер обмениваются информацией пока соединение не будет закрыто или прервано.
Ну давайте попробуем. Как и в прошлом туторе нашей жертвой будет mail.ru. Адрес: smtp.mail.ru, прослушиваемые порты 25, 2525 и 587. Будим юзать 25
Итак, наш код:
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Опа, все супер)). Продолжим.
Основной процедурой в SMTP является передача почты (Mail Procedure). Далее идут процедуры форвардинга почты (Mail Forwarding), проверка имён почтового ящика и вывод списков почтовых групп. Самой первой процедурой является открытие канала передачи, а последней - его закрытие.
Команды SMTP указывают серверу, какую операцию хочет произвести клиент. Команды состоят из ключевых слов, за которыми следует один или более параметров. Ключевое слово состот из 4-х символов и разделено от аргумента одним или несколькими пробелами. Каждая командная строка заканчивается символами CRLF (так как мы будем использовать ф-цию writeline(), то нам это не надо). Вот список основных команд:
HELO
MAIL FROM:
RCPT TO:
DATA
RSET
NOOP
QUIT
Резберем каждую команду.
Первая в нашем списке команда
HELO.
Эта команда передает серверу наш IP адрес. У нее один единственный параметр, в котором нужно указать IP адрес или url адрес сервера. В нашем случае это smtp.mail.ru
Попробуем.
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
WriteLine tcp,"HELO smtp.mail.ru"
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Так, мы передали серверу наш IP адрес.
Что дальше? А дальше мы уже можем начинать отправку письма,
НО smtp сервер mail.ru требует авторизацию пользователя. Это я прочитал на сайте
. Поверим на слово. Авторизируемся
.
Наш адрес электронной почты
[email protected] с паролем 12344321. Он реально рабочий).
А это очень важно!!! Пароль и Логин отправляется в зашифрованном виде, а именно в base64. Я на скорую руку настрочил ф-цию, так что не судите строго. Она для примера. И еще я взял ф-цию для перевода из 2-й системы счисления в 10-ную (это надо для base64)
Function encode_base64$(value$)
abc$="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
For b=1 To Len(value$)
char$=Left(value$,b)
char$=Right(char$,1)
ValueIn2$=ValueIn2$+Right(Bin$(Asc(char$)),8)
Next
;Print ValueIn2$
For b=1 To Len(ValueIn2$) / 6
char$=Left(ValueIn2$,6*b)
char$=Right(char$,6)
num=ToInt(char$,2)
res$=res$+Right(Left(abc$,num+1),1)
Next
If(6*(b-1)<>Len(ValueIn2$)) Then
char$=Right(ValueIn2$,Len(ValueIn2$)-(6*(b-1)))
len_char=6-Len(char$)
For c=1 To (len_char)
char$=char$+"0"
Next
res$=res$+Right(Left(abc$,ToInt(char$,2)+1),1)
EndIf
If(Len(value$)>3) And Len(value$) Mod 3 <> 0 Then
Lenn=(Len(value$) Mod 3)
For b=1 To 3-lenn
res$=res$+"="
Next
ElseIf (Len(value$)>3)
Lenn=(Len(value$))
For b=1 To 3-lenn
res$=res$+"="
Next
End If
Return res$
End Function
Function ToInt(inputnum$,base)
If base=10 Return inputnum
If base>10 Return 0
l=Len(inputnum$)
For i=0 To l-1
rightnum=Right(inputnum$,1)
If rightnum<base Then
If rightnum>0 Then
intnum#=intnum#+base^i*rightnum
EndIf
Else Return 0
EndIf
inputnum$=Left$(inputnum$,Len(inputnum$)-1)
Next
Return intnum
End Function
Теперь о том, как нам авторизоваться.
Первое что нам надо, это дать серверу понять что мы хотим авторизоваться. Для этого надо передать команду
AUTH LOGIN.
Попробуем, только давайте договоримся. Из за ф-ции base64 код уж больно грамоздкий получается. Я не буду ее вписывать в последующие примеры. Но знайте что она там должна присутствовать
.
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
WriteLine tcp,"HELO smtp.mail.ru"
Print ReadLine$(tcp)
WriteLine tcp,"AUTH LOGIN"
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Черти что получаем в ответ. Это зашифрованное слово в base64. Если мы его декодируем то получим «Username:». Ага! Тоесть сервер ждет когда же мы отправим ему наш логин.
Ну что ж, отправим(помним, что логин и пароль передаются в base64):
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
WriteLine tcp,"HELO smtp.mail.ru"
Print ReadLine$(tcp)
WriteLine tcp,"AUTH LOGIN"
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“Boolean_pop3_ex”)
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Смотрим …
Угу, что же это за слово такое?! Ну давайте его декодируем. Получаем «Password:». То есть наш кодированный логин был принят и сервер ожидает когда мы отправим ему пароль(тоже в base64)
Go!
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
WriteLine tcp,"HELO smtp.mail.ru"
Print ReadLine$(tcp)
WriteLine tcp,"AUTH LOGIN"
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“Boolean_pop3_ex”)
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“12344321”)
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Посмотрим…
Так, все прошло успешно, мы авторизовались! ))))
Теперь можно приступить непосредственно к написанию письма.
При отправке почты передаём некоторые нужные данные (отправитель, получатель и само письмо)
И первая команда, которая нам потребуется, это
MAIL FROM: . Эта команда указывает E-mail адрес отправителя, адрес долен быть тот, под которым авторизовались (в нашем случае
[email protected]).
Потестим:
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
WriteLine tcp,"HELO smtp.mail.ru"
Print ReadLine$(tcp)
WriteLine tcp,"AUTH LOGIN"
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“Boolean_pop3_ex”)
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“12344321”)
Print ReadLine$(tcp)
WriteLine tcp,"MAIL FROM: [email protected]"
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Смотрим:
Собственно вот и ответ сервера. Все в норме)
Продолжаем.
Теперь нам нужно указать e-mail адрес получателя. А осуществим мы это с помощью команды
RCPT TO: . Я буду отправлять письмо на свой e-mail:
[email protected]
Испробуем команду:
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
WriteLine tcp,"HELO smtp.mail.ru"
Print ReadLine$(tcp)
WriteLine tcp,"AUTH LOGIN"
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“Boolean_pop3_ex”)
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“12344321”)
Print ReadLine$(tcp)
WriteLine tcp,"MAIL FROM: [email protected]"
Print ReadLine$(tcp)
WriteLine tcp,"RCPT TO: [email protected]"
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Смотрим:
И эта команда прокатила без ошибок. Можно продолжать.
А дальше следует команда
DATA, без единого аргумента. Она сообщает серверу что мы начнем писать само письмо)
Тестим:
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
WriteLine tcp,"HELO smtp.mail.ru"
Print ReadLine$(tcp)
WriteLine tcp,"AUTH LOGIN"
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“Boolean_pop3_ex”)
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“12344321”)
Print ReadLine$(tcp)
WriteLine tcp,"MAIL FROM: [email protected]"
Print ReadLine$(tcp)
WriteLine tcp,"RCPT TO: [email protected]"
Print ReadLine$(tcp)
WriteLine tcp,"DATA"
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Результат:
Сервер воспринял команду. Так же он сообщил нам, что после того как мы введем текст письма, нам следует отправить знак «.» на отдельно строке.
Приступим.
Как более красиво и с понтами оформить письмо я расскажу в своем следующем туторе, а сегодня для меня была задача познакомить вас с основными командами протокола SMTP. Отправим что нить по проще.
Чтобы наше письмо не расценивалось как спам, надо указать от кого оно, тему, ну и укажем название нашего клиента)) пусть оно будет “ Boolean mail client ”
Итак, сначала надо указать от кого оно:
From: Boolean_ex <
[email protected]>
Далее укажем кому:
To:
[email protected]
Тепер тему письма:
Subject: Просто проверка
Ну и название нашего клиента:
X-Mailer: Boolean mail client
Ну а текст наш будет:
Ура, все работает!
Теперь надо это все отправить. Отправлять надо на отдельных строках.
Получается так:
WriteLine tcp,"From: Boolean_ex <[email protected]>"
WriteLine tcp,"To: [email protected]”
WriteLine tcp,"Subject: Просто проверка”
WriteLine tcp,"X-Mailer: Boolean mail client”
WriteLine tcp,”Ура, все работает!”
Ах да, мы забыли поставить знак «.», Так как письмо мы уже дописали.
WriteLine tcp,"From: Boolean_ex <[email protected]>"
WriteLine tcp,"To: [email protected]”
WriteLine tcp,"Subject: Просто проверка”
WriteLine tcp,"X-Mailer: Boolean mail client”
WriteLine tcp,”Ура, все работает!”
WriteLine tcp,”.”
Теперь вставим это в нашу программу:
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
WriteLine tcp,"HELO smtp.mail.ru"
Print ReadLine$(tcp)
WriteLine tcp,"AUTH LOGIN"
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“Boolean_pop3_ex”)
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“12344321”)
Print ReadLine$(tcp)
WriteLine tcp,"MAIL FROM: [email protected]"
Print ReadLine$(tcp)
WriteLine tcp,"RCPT TO: [email protected]"
Print ReadLine$(tcp)
WriteLine tcp,"DATA"
Print ReadLine$(tcp)
WriteLine tcp,"From: Boolean_ex <[email protected]>"
WriteLine tcp,"To: [email protected]”
WriteLine tcp,"Subject: Просто проверка”
WriteLine tcp,"X-Mailer: Boolean mail client”
WriteLine tcp,”Ура, все работает!”
WriteLine tcp,”.”
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Фух, испробуем:
Ага, все удачно. Сервер выдал нам ид, значит письмо отправлено. Пойду взгляну в свой ящик
Все супер. Но давайте будем порядочными людьми и попрощаемся с сервером. Командой
QUIT
OpenTCPStream("smtp.mail.ru",25)
Print ReadLine$(tcp)
WriteLine tcp,"HELO smtp.mail.ru"
Print ReadLine$(tcp)
WriteLine tcp,"AUTH LOGIN"
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“Boolean_pop3_ex”)
Print ReadLine$(tcp)
WriteLine tcp,encode_base64$(“12344321”)
Print ReadLine$(tcp)
WriteLine tcp,"MAIL FROM: [email protected]"
Print ReadLine$(tcp)
WriteLine tcp,"RCPT TO: [email protected]"
Print ReadLine$(tcp)
WriteLine tcp,"DATA"
Print ReadLine$(tcp)
WriteLine tcp,"From: Boolean_ex <[email protected]>"
WriteLine tcp,"To: [email protected]”
WriteLine tcp,"Subject: Просто проверка”
WriteLine tcp,"X-Mailer: Boolean mail client”
WriteLine tcp,”Ура, все работает!”
WriteLine tcp,”.”
Print ReadLine$(tcp)
WriteLine tcp,”QUIT”
Print ReadLine$(tcp)
CloseTCPStream tcp
WaitKey()
Вот собственно и все.
А нет…
Еще парочка команд:
RSET - указывает серверу прервать выполнение текущего процесса. Все сохранённые данные (отправитель, получатель и др) удаляются. Сервер должен отправить положительный ответ.
Ну думаю не надо примеров с ней.
И команда
NOOP. Ничего не делает, тупо выдает положительный ответ. В общем то это все команды, с которыми я хотел познакомить вас сегодня. В следующем туторе я попытаюсь объяснить как отправить письмо с вложенными файлами и например в HTML формате. Все на этом, удачи