Теперь посмотрим на практическую реализацию БМТР-клиента. Давайте создадим новый проект и форму (рис. 5.5).

5.2.2. Реализация SMTP-клиента

Рис. 5.5. Форма будущей программы

На форме имеются три поля ввода для указания следующей информации:

1. Адрес БМТР-сервера, через который будет отправляться письмо В почтовых клиентах его выносят в настройки, мы укажем настройки в главном окне.

2. Порт сервера. Чаще всего используется порт 25, но в моей сети на прокси-сервере используется 25025, поэтому я прописал этот порт в исходный код Возможны и другие данные, тогда порт изменяется.

3. Адрес получателя нашего сообщения.

Помимо этого на форме расположены два компонента ТМешо для ввода текста сообщения и отображения хода отправки сообщения (всей информации, отправляемой и получаемой по сети).

Код, который должен выполняться по нажатии кнопки Отправить, приведен в листинге 5.4.

Листинг 5.4. Отправка e-mail сообщения с помощью Win API procedure ТТСРС1ientForm.btSendCllck(Sender: TObject): var wData: WSADATA. sServerListen: TSOCKET: server_addr: sockaddr_in: sRecvBuff: array [0..255] of char: TempStr: AnsiString; i, iRet: Integer; begin mmLog.Clear:

// Загрузка WinSock

if WSAStartup(MAKEWORDd.l). wData) <> 0 then begin MessageBox(0, 'He могу загрузить WinSock'. 'Ошибка'. 0); exit:

end;

// Создание сокета

sServerListen := socket(PF_INET. SOCKJTREAM, IPPR0T0JP);

if sServerListen = INVALID_SOCKET then begin MessageBox(0, 'Ошибка создания сокета'. 'Ошибка', 0); exit.

end:
// Заполнение структуры адреса server_addr.sin_addr.s_addr := htonl(INADDR_ANY). server_addr.sin_family = AF_INET: server_addr.sin_port := htons(StrToInt(edPort.Text)): server_addr.sih_addr := LookupName(edServer.Text);
if (connect(sServerListen, server_addr. sizeof(server_addr)) =
S0CKETJRR0R) then
begin
TestWinSockError('Connect');
exit; (
end:
TestFuncError(recv(sServerListen. sRecvBuff. 1024. 0), 'Ошибка приветствия');
TempStr := sRecvBuff:

продолжение

Листинг 5.4 (продолжение) mmLog.Lines.Add('<'+Сору(TempStr. 1. Pos(#13. TempStr))): Appli cation.ProcessMessages:

// "Поприветствуем" сервер TempStr := 'HELO ,+GetLocalHost+#13+#10: CopyMemory(@sRecvBuff. PChar(TempStr). Length(TempStr)): TestFuncError(send(sServerListeh. sRecvBuff.

Length(TempStr). 0). 'Send HELO'): mmLog.Lines.Add('>'+Copy(TempStr. 1. Pos(#13. TempStr)));
TestFuncError(recv(sServerListen. sRecvBuff. SizeOf(sRecvBuff). 0).
'Ошибка приветствия');
TempStr := sRecvBuff;
mmLog.Lines Add('<'+Copy(TempStr 1, Pos(#13, TempStr))): Appli cation.ProcessMessages:

// Скажем, от кого письмо

TempStr := 'MAIL FROM:<vasya@pupkin.ru>'+#13+#10. CopyMemory(@sRecvBuff. PChar(TempStr). Length(TempStr)); TestFuncError(send(sServerLi sten, sRecvBuff.
Length(TempStr). 0). 'Send MAIL FROM');
mmLog.Lines.Add('>'+Copy(TempStr. 1. Pos(#13. TempStr))):
TestFuncError(recv(sServerListen. sRecvBuff. SizeOf(sRecvBuff). 0).

'Ошибка адресата'):

TempStr := sRecvBuff;

mmLog.Lines.Add('<'+Copy(TempStr. 1. Pos(#13, TempStr))); Appli cati on.ProcessMessages г

// Скажем, для кого письмо TempStr := 'RCPT T0:<'+edSendTo.Text+'>'+#13+#10; •Co,pyMemory(@sRecvBuff. PChar(TempStr). Length(TempStr)). TestFuncError(send(sServerLi sten, sRecvBuff.

Length(TempStr). 0), 'Send MAIL TO');
mmLog.Lines.Add('>'+Copy(TempStr. 1. Pos(#13. TempStr)));
TestFuncError(recv(sServerLTsten. sRecvBuff, SizeOf(sRecvBuff), 0).

'Ошибка получателя'):

TempStr := sRecvBuff;
mmLog.Lines.Add('<'+Copy(TempStr, 1. Pos(#13. TempStr))): Appli cati on.ProcessMessages:
// Начало отправки данных TempStr := 'DATA'+#13+#10;
CopyMemory(@sRecvBuff. PChar(TempStr), Length(TempStr)); TestFuncError(send(sServerListen, sRecvBuff, Length(TempStr). 0).
'Send DATA');
mmLog.Ltnes.Add('>'+Copy(TempStr. 1. Pos(#13, TempStr)));
TestFuncError(recv(sServerListen. sRecvBuff. SizeOf(sRecvBuff). 0).

'Ошибка начала данных'):

TempStr := sRecvBuff;
mmLog.Lines.Add('<'+Copy(TempStr. 1. Pos(#13. TempStr))): Appli cati on.ProcessMessages:

//////////////////// // Заголовок ///////////////////// // Для

TempStr := 'From:<vasya@pupkin.ru>'+#13+#10: CopyMemory(@sRecvBuff. PChar(TempStr). Length(TempStr)); TestFuncError(send(sServerListen. sRecvBuff, Length(TempStr). 0).
'Send MAIL FROM'): mmLog.Lines.AddC'>'+Copy(TempStr. 1. Pos(#13, TempStr))):

// От

TempStr := 'To:<'+edSendTo.Text+'>'+#13+#10: CopyMemory(@sRecvBuff, PChar(TempStr). Length(TempStr)): TestFuncError(send(sServerListen. sRecvBuff. Length(TempStr). 0).
'Send MAIL TO'): mmLog.Lines.AddC'>'+Copy(TempStr. 1. Pos(#13, TempStr))):

// Кодировка

TempStr := 'Mime-Version: 1.0'+#13+#10+'Content-Type: text/plain: charset = "us-ascii'+#13+#10:
CopyMemory(@sRecvBuff, PChar(TempStr). Length(TempStr)), TestFuncError(send(sServerListen. sRecvBuff. Length(TempStr), 0), 'Send MAIL TO'): mmLog.Lines.AddC'>'+Copy(TempStr, 1. Pos(#13. TempStr))):

for i := 0 to mmMessage.Lines.Count-1 do begin // Отправляем строку сообщения TempStr := mmMessage.Lines[i]+#13+#10: while TempStro"' do begin CopyMemory(@sRecvBuff, PChar(TempStr). Length(TempStr)): IRet := sendCsServerListen. sRecvBuff, Length(TempStr). 0):

if iRet = S0CKETJRR0R then break:
mmLog.Lines.AddC'>'+Copy(TempStr. 1. Pos(#13, TempStr))):

// Удаляем отправленные данные из переменной TempStr DeleteCTempStr. 1, iRet):

end:
end:
продолжение &

Листинг 5.4 (продолжение) II Конец сообщения TempStr := #13+#10+'.'+#13+#10.

CopyMemory(@sRecvBuff. PChar(TempStr). Length(TempStr)): TestFuncError(send(sServerListen. sRecvBuff. Length(TempStr). 0).
"Send "):
nmLog.Lines.Add('>"+Copy(TempStr. 1. Pos(#13. TempStr))):
TestFuncError(recv(sServerListen. sRecvBuff. SizeOf(sRecvBuff). 0).

'Ошибка конца сообщения'):

TempStr •= sRecvBuff:
mmLog.Lines.Add("<'+Copy(TempStr. 1. Pos(#13. TempStr))): Appli cati on.ProcessMessages:

// Выход

TempStr := 'QUIT'+#13+#10:
CopyMemory(@sRecvBuff. PChar(TempStr). Length(TempStr)): TestFuncError(send(sServerListen. sRecvBuff. Length(TempStr). 0).
'Send QUIT"):
mmLog.Lines.AddC>'+Copy(TempStr. 1. Pos(#13. TempStr))):
TestFuncError(recv(sServerListen. sRecvBuff. Size0f(sRecvBuff). 0).

"Ошибка выхода'):

TempStr := sRecvBuff:
mmLog.Lines.Add('<'+Copy(TempStr. 1. Pos(#13. TempStr))): Appli cation.ProcessMessages;
CloseSocket(sServerListen):
end:

Как видите, мы просто посылаем команды SMTP в текстовом режиме на заданный порт SMTP-сервера (рис. 5.6).

5.2.2. Реализация SMTP-клиента

Рис. 5.6. Программа в работе

5.2.1. Описание RFC-821 || Оглавление || 5.2.3. Передача больших строк


Delphi в шутку и всерьез: что умеют хакеры



Новости за месяц

  • Декабрь
    2021
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31