Главная страница

Глубины Indy. 2. Техническая поддержка


Скачать 1.03 Mb.
Название2. Техническая поддержка
Дата02.05.2018
Размер1.03 Mb.
Формат файлаpdf
Имя файлаГлубины Indy.pdf
ТипДокументы
#42664
страница15 из 16
1   ...   8   9   10   11   12   13   14   15   16
20.1.6.1.2. Не явное разрушение
.Net разделяет эти функции – финализации и освобождения памяти, поскольку памятью заведует .NET. .Net использует неявное разрушение. Если вы работали с интерфейсами, то семантика подсчета ссылок, используемая в интерфейсах аналогична.
Вместо явного разрушения, когда объект сам разрушается, CLR подсчитывает ссылки на объект. Когда объект больше не используется, то он помечается для разрушения.
20.1.6.2. Сборка мусора (Garbage Collection)
.Net использует сборку мусора, что бы очистить память используемую объектом. Это название процесса, который определят, что объект больше используется и освобождает занятую им память.
Сборка мусора .NET очень сложная и даже базовая информация заслуживает отдельной главы, если даже не статьи.

114
Подобно явному и неявному разрушению, сборка мусора имеет малое влияние на перенос приложения. Поскольку для процедуры переноса, сборка мусора является ящиком фокусника, который заботится о разрушении объекта за вас.
20.1.7. Шаги по переносу
Перенос приложений в Delphi .NET для большинства приложений будет очень значимым и потребует определенной осторожности. Для большинства объектно-ориентированного кода, проще чем кажется. Данная статья не может уменьшить количество работы по переносу, но поможет вам сделать это легче. Она позволит уменьшить количество ошибок и предназначена для быстрой реализации переноса.
20.1.7.1. Удаление предупреждений (Unsafe Warnings)
To remove unsafe warnings, load the target project into Delphi 7. With the unsafe warnings turned on, perform a build all. Delphi will produce a series of unsafe warnings. Each warning needs to be eliminated. This may easily be the biggest step in porting your application.
20.1.7.2. Модули и пространство имен
Директивы Uses должны быть преобразованы к использованию пространства имен.
Если код требует одновременного использования в Windows и в .NET framework данные модули должны использовать IFDEF как указано. Константа CLR определена в Delphi
.NET.
uses
{$IFDEF CLR}
Borland.Win32.Windows
{$ELSE}
Windows
{$ENDIF}
,
{$IFDEF CLR}
Borland.Delphi.SysUtils
{$ELSE}
SysUtils
{$ENDIF}
,
{$IFDEF CLR}
Borland.Vcl.Forms
{$ELSE}
Forms
{$ENDIF}
;
Пространство имен будет увидено. Три главных из них – это Borland.Win32 (Windows),
Borland.Delphi (RTL) and Borland.VCL (VCL for .NET).
20.1.7.3. Преобразование DFM
Delphi for .NET пока не поддерживает формат DFM. Это возможно будет в будущем, так что данный шаг требуется если вы желаете использовать бета версию DCCIL.
Поскольку DFM не поддержаны, все формы должны быть сконструированы с помощью кода. Есть также программа разработанная для выполнения данной задачи, которая может быть использована с нормальным приложениями Delphi.
20.1.7.4. Преобразование файла проекта
Application.CreateForm более не поддержан, так что формы должны быть созданы вручную, как обычные компоненты. Для установки главной формы приложения, установите свойство Application.MainForm перед вызовом Application.Run.
20.1.7.5. Разрешение с различиями в классах

115
Во время компиляции могут проявиться различия между VCL for .NET и VCL, поскольку появились небольшие различия между VCL и Visual CLX. Каждое из этих различий должно быть разрешено с помощью IFDEF.
20.1.7.6. Нужна удача
Если вам повезло, то ваш проект преобразован и работает нормально.
Перенос – это не только перекомпиляция и потребует некоторого времени. Перенос в
.NET требует подобных усилий, которые нужны для переноса в из VCL приложений в
Visual CLX. Хотя время и усилия значительны, но это все равно меньше, чем писать с нуля и позволяет делать кросс платформенную разработку, так как код будет повторно использоваться и там и там, конечно если он спланирован должным образом.
20.1.8. Благодарности
Я использовал много источников. Я извиняюсь, если я кого-то забыл указать в благодарностях. Я желаю поблагодарить следующих товарищей: John Kaster, Brian Long,
Bob Swart, Lino Tadros, Danny Thorpe, Eddie Churchill, Doychin Bondzhev.
21. Об авторах
21.1. Chad Z. Hower a.k.a Kudzu
Чад Хувер (Chad Z. Hower), известный так же, как "Kudzu" является автором и координатором проекта Internet Direct (Indy). Indy состоит из более, чем 110 компонент и является частью Delphi, Kylix и C++ Builder. В опыт Чада входит работа с трудоустройством, безопасность, химия, энергетика, торговля, телекоммуникации, беспроводная связь и страховая индустрии. Особая область Чада это сети TCP/IP, программирование, межпроцессорные коммуникации, распределенные вычисления,
Интернет протоколы и объектно-ориентированное программирование.
Когда он не занимается программирование, то он любит велосипед, каяк, пешие прогулки, лыжи, водить и просто чем ни будь заниматься вне дома. Чад, чей лозунг "Программирование это искусство, а не ремесло", также часто публикует статьи, программы, утилиты и другие вещи на Kudzu World http://www.Hower.org/Kudzu/.
Чад как истинный американский путешественник, проводит свое лето в Санкт-
Петербурге, Россия, а зиму в Лимасоле на Кипре.
Чад доступен через Веб форму.
Чад является ведущим разработчиком в Atozed Software.
21.2. Hadi Hariri
Hadi Hariri – это старший разработчик и ведущий проекта в Atozed Computer Software Ltd.
(http://www.atozedsoftware.com/) и также помощник координатора проекта Internet Direct
(Indy), Open-source проект TCP/IP компонент, который включен в Kylix и Delphi 6. раньше работал для ISP и в программисткой компании, он имеет твердые знания Internet и клиент- серверных приложений, как сетевой администратор и администратор по безопасности.

116
Hadi женат и проживает в Испании, где он главный авто для журнала по Delphi и участник
Borland Conferences и пользовательских групп.
Создано: 19.04.2009
Исходный код IdSMTP.pas
Исходный код компонента даёт понимание его алгоритма работы с принимающим почтовым сервером.
unit
IdSMTP;
interface
uses
Classes,
IdGlobal,
IdMessage,
IdEMailAddress,
IdHeaderList,
IdMessageClient;
type
TAuthenticationType = (atNone, atLogin);
const
ID_TIDSMTP_AUTH_TYPE = atNone;
type
TIdSMTP =
class
(TIdMessageClient)
protected
FDidAuthenticate: Boolean;
FAuthenticationType: TAuthenticationType;
FAuthSchemesSupported: TStringList;
FMailAgent:
string
;
FPassword:
string
;
FUserId:
string
;
procedure
GetAuthTypes;
function
IsAuthProtocolAvailable(Auth: TAuthenticationType)
: Boolean;
virtual
;
public
procedure
Assign(Source: TPersistent);
override
;
function
Authenticate: Boolean;
virtual
;
procedure
Connect;
override
;
constructor
Create(AOwner: TComponent);
override
;
destructor
Destroy;
override
;
procedure
Disconnect;
override
;
class
procedure
QuickSend(const AHost, ASubject, ATo,
AFrom, AText:
string
);
procedure
Send(AMsg: TIdMessage);
virtual
;
property
AuthSchemesSupported: TStringList
read
FAuthSchemesSupported;
published
property
AuthenticationType: TAuthenticationType
read
FAuthenticationType
write
FAuthenticationType
default
ID_TIDSMTP_AUTH_TYPE;
property
MailAgent:
string
read
FMailAgent
write
FMailAgent;

117
property
Password:
string
read
FPassword
write
FPassword;
property
UserId:
string
read
FUserId
write
FUserId;
property
Port
default
IdPORT_SMTP;
end
;
implementation
uses
IdCoder3To4,
IdResourceStrings,
SysUtils;
procedure
TIdSMTP.Assign(Source: TPersistent);
begin
if
Source
is
TIdSMTP
then
begin
AuthenticationType := TIdSMTP(Source).AuthenticationType;
Host := TIdSMTP(Source).Host;
MailAgent := TIdSMTP(Source).MailAgent;
Password := TIdSMTP(Source).Password;
Port := TIdSMTP(Source).Port;
UserId := TIdSMTP(Source).UserId;
end
else
inherited
;
end
;
function
TIdSMTP.Authenticate: Boolean;
function
AuthLogin: Boolean;
begin
SendCmd(
'auth LOGIN'
,
3 34);
SendCmd(Base64Encode(UserId),
3 34);
SendCmd(Base64Encode(Password),
2 35);
Result := True;
end
;
begin
Result := False;
case
FAUthenticationType
of
atLogin: Result := AuthLogin;
end
;
FDidAuthenticate := True;
end
;
procedure
TIdSMTP.Connect;
begin
inherited
;
try
GetResponse([
2 20]);
FAuthSchemesSupported.Clear;
if
SendCmd(
'ehlo '
+ LocalName) =
2 50
then
begin
GetAuthTypes;
end
else
begin
SendCmd(
'Helo '
+ LocalName,
2 50);
end
;
except
Disconnect;
raise
;
end
;

118
end
;
constructor
TIdSMTP.Create(AOwner: TComponent);
begin
inherited
;
FAuthSchemesSupported := TStringList.Create;
FAuthSchemesSupported.Duplicates := dupIgnore;
Port := IdPORT_SMTP;
end
;
destructor
TIdSMTP.Destroy;
begin
FreeAndNil(FAuthSchemesSupported);
inherited
;
end
;
procedure
TIdSMTP.Disconnect;
begin
try
if
Connected
then
begin
WriteLn(
'Quit'
);
end
;
finally
inherited
;
FDidAuthenticate := False;
end
;
end
;
procedure
TIdSMTP.GetAuthTypes;
var
Iterator: Integer;
Buffer:
string
;
ListEntry:
string
;
begin
Iterator :=
1
;
while
Iterator < FCmdResultDetails.Count
do
begin
Buffer := UpperCase(FCmdResultDetails[Iterator]);
if
(IndyPos(
'AUTH'
, Buffer) =
5
)
and
((Copy(Buffer,
9
,
1
) =
' '
)
or
(Copy(Buffer,
9
,
1
) =
'='
))
then
begin
Buffer := Copy(Buffer,
1 0, Length(Buffer));
while
Buffer <>
''
do
begin
StringReplace(Buffer,
'='
,
' '
, [rfReplaceAll]);
ListEntry := Fetch(Buffer,
' '
);
if
(FAuthSchemesSupported.IndexOf(ListEntry) = -
1
)
then
FAuthSchemesSupported.Add(ListEntry);
end
;
end
;
Inc(Iterator);
end
;
end
;
function
TIdSMTP.IsAuthProtocolAvailable(
Auth: TAuthenticationType): Boolean;
begin
case
Auth
of
atLogin: Result := (FAuthSchemesSupported.IndexOf(
'LOGIN'
) <> -
1
);
else
Result := False;
end
;

119
end
;
class
procedure
TIdSMTP.QuickSend(const AHost, ASubject, ATo,
AFrom, AText:
string
);
var
SMTP: TIdSMTP;
Msg: TIdMessage;
begin
SMTP := TIdSMTP.Create(nil);
try
Msg := TIdMessage.Create(SMTP);
with
Msg
do
begin
Subject := ASubject;
Recipients.EMailAddresses := ATo;
From.Text := AFrom;
Body.Text := AText;
end
;
with
SMTP
do
begin
Host := AHost;
Connect;
try
;
Send(Msg);
finally
Disconnect;
end
;
end
;
finally
SMTP.Free;
end
;
end
;
procedure
TIdSMTP.Send(AMsg: TIdMessage);
procedure
WriteRecipient(const AEmailAddress: TIdEmailAddressItem);
begin
SendCmd(
'RCPT to:<'
+ AEMailAddress.Address +
'>'
,
2 50);
end
;
procedure
WriteRecipients(AList: TIdEmailAddressList);
var
i: integer;
begin
for
i :=
0
to
AList.count -
1
do
begin
WriteRecipient(AList[i]);
end
;
end
;
function
NeedToAuthenticate: Boolean;
begin
if
FAuthenticationType <> atNone
then
begin
Result := IsAuthProtocolAvailable(FAuthenticationType)
and
(FDidAuthenticate = False);
end
else
begin
Result := False;
end
;
end
;

120
begin
SendCmd(
'Rset'
);
if
NeedToAuthenticate
then
begin
Authenticate;
end
;
SendCmd(
'Mail from:<'
+ AMsg.From.Address +
'>'
,
2 50);
WriteRecipients(AMsg.Recipients);
WriteRecipients(AMsg.CCList);
WriteRecipients(AMsg.BccList);
SendCmd(
'Data'
,
3 54);
AMsg.ExtraHeaders.Values[
'X-Mailer'
] := MailAgent;
SendMsg(AMsg);
SendCmd(
'.'
,
2 50);
end
;
end
Пример с исходниками простейшего SMTP сервера
Просетйший SMTP север из примеров работы с компонентами Indy
{ $HDR$}
{**********************************************************************}
{ Unit archived using Team Coherence }
{ Team Coherence is Copyright 2002 by Quality Software Components }
{ }
{ For further information / comments, visit our WEB site at }
{ http://www.TeamCoherence.com }
{**********************************************************************}
{}
{ $Log: 108528: Main.pas
{
{ Rev 1.0 14/08/2004 12:29:18 ANeillans
{ Initial Checkin
}
{
Demo Name: SMTP Server
Created By: Andy Neillans
On: 27/10/2002
Notes:
Demonstration of SMTPServer (by use of comments only!!)
Read the RFC to understand how to store and manage server data, and
therefore be able to use this component effectivly.
Version History:
14th Aug 04: Andy Neillans
Updated for Indy 10, rewritten IdSMTPServer
12th Sept 03: Andy Neillans
Cleanup. Added some basic syntax checking for example.
Tested:
Indy 10:
D5: Untested
D6: Untested
D7: Untested
}
unit
Main;

121
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
IdBaseComponent, IdComponent, IdTCPServer, IdSMTPServer, StdCtrls,
IdMessage, IdEMailAddress, IdCmdTCPServer, IdExplicitTLSClientServerBase;
type
TForm1 =
class
(TForm)
Memo1: TMemo;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
ToLabel: TLabel;
FromLabel: TLabel;
SubjectLabel: TLabel;
IdSMTPServer1: TIdSMTPServer; btnServerOn: TButton; btnServerOff: TButton;
procedure
btnServerOnClick(Sender: TObject);
procedure
btnServerOffClick(Sender: TObject);
procedure
IdSMTPServer1MsgReceive(ASender: TIdSMTPServerContext;
AMsg: TStream;
var
LAction: TIdDataReply);
procedure
IdSMTPServer1RcptTo(ASender: TIdSMTPServerContext;
const
AAddress:
String
;
var
VAction: TIdRCPToReply;
var
VForward:
String
);
procedure
IdSMTPServer1UserLogin(ASender: TIdSMTPServerContext;
const
AUsername, APassword:
String
;
var
VAuthenticated: Boolean);
procedure
IdSMTPServer1MailFrom(ASender: TIdSMTPServerContext;
const
AAddress:
String
;
var
VAction: TIdMailFromReply);
procedure
IdSMTPServer1Received(ASender: TIdSMTPServerContext;
AReceived:
String
);
private
{ Private declarations }
public
{ Public declarations }
end
;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure
TForm1.btnServerOnClick(Sender: TObject);
begin
btnServerOn.Enabled := False; btnServerOff.Enabled := True;
IdSMTPServer1.active := true;
end
;
procedure
TForm1.btnServerOffClick(Sender: TObject);
begin
btnServerOn.Enabled := True; btnServerOff.Enabled := False;
IdSMTPServer1.active := false;
end
;
procedure
TForm1.IdSMTPServer1MsgReceive(ASender: TIdSMTPServerContext;
AMsg: TStream;
var
LAction: TIdDataReply);
var
LMsg : TIdMessage;

122
LStream : TFileStream;
begin
// When a message is received by the server, this event fires.
// The message data is made available in the AMsg : TStream.
// In this example, we will save it to a temporary file, and the load it
using
// IdMessage and parse some header elements.
LStream := TFileStream.Create(ExtractFilePath(Application.exename) +
'test.eml'
, fmCreate);
1   ...   8   9   10   11   12   13   14   15   16


написать администратору сайта