Цель работы: получить практику работы с компонентами IdTrivialFTP и IdTrivialFTPServer и освоить механизм работы протокола передачи файлов ТРТР.
1. ТЕОРЕТИЧЕСКОЕ ВВЕДЕНИЕ
В теоретическом введении рассматриваются следующие вопросы.
• Протокол TFTP.
• Компонент IdTrivialFTP.
• Компонент IdTrivialFTPServer.
1.1. Протокол TFTP
TFTP-протокол - это простейший протокол передачи файлов. Он работает поверх транспортного протокола UDP и обеспечивает выполнение только самых элементарных операций передачи файлов, а именно записи и чтения файлов. TFTP был разработан как простой и легкий в применении протокол. Он не позволяет вызывать список каталога и не имеет никаких средств аутентификации, но может передавать 8-битную информацию в соответствии со всеми стандартами Internet.
Поскольку передача данных осуществляется поверх UDP, протокол TFTP реализует собственные методы надежной доставки данных - пакеты подтверждения, нумерация блоков данных и пакетов подтверждения и т. п. Все это очень похоже на упрощенный вариант эмуляции протокола TСР.
TFTP работает лишь пятью командами:
1) read request (RRQ) - запрос на чтение;
2) write request (WRQ) - запрос на запись;
3) data (DATA) - пакет данных;
4) acknowledgment (АСК) - подтверждение;
5) error (ERROR) - ошибка.
Процесс передачи данных начинается с поступления от клиента TFTP на сервер запроса на чтение или запись файла. Соединение устанавливается после получения подтверждения готовности на один из запросов либо на запись - WRQ, либо на чтение - RRQ.
При открытии соединения каждая из сторон выбирает (случайный образом) уникальный идентификатор -TID, который используется в UDP как порт соединения. Каждый пересылаемый пакет ассоциирован с двумя TID, соответствующими каждой стороне соединения. Первоначальный запрос отправляется инициатором TFTP-соединения на UQP-порт 69 (порт инициализации), в котором указывался порт соединения. Дальнейший обмен уже происходит через порты, выбранные участниками передачи данных.
Если сервер разрешает запрос, соединение открывается и указанный файл передается (блоками по 512 байт). Каждый пакет передаваемых данных содержит один блок (512 байт) передаваемых данных и номер блока в передаваемом потоке. Поступление каждого блока на хост назначения должно быть подтверждено пакетом АСК (подтверждение) с номером поступившего блока. Только после получения пакета подтверждения будет отравлен следующий пакет данных.
Если длина пакета менее 512 байт это служит сигналом для закрытия канала связи. В случае потери пакта при передаче, через некоторый промежуток времени сервер отправит этот пакет данных повторно.
Три типа ситуаций порождают отправку ошибочных пакетов:
1) не подтвержден запрос, например, не был найден файл, нет прав доступа и др;
2) неправильный формат пакета, например, произошла ошибка коммутации и др;
3) потеря доступа к требуемому ресурсу.
При большом количестве сообщений об ошибках соединение может быть закрыто по инициативе одной из сторон.
TFTP-транзакции работают по следующей схеме:
1) хост А отправляет запрос WRQ хосту В. Порт источника - TIDА, порт назначения - 69. Пакет содержит имя файла, тип передачи (ascii, 8 бит или др.);
2) хост В отправляет АСК (номер блока - 0) хосту А. Порт источника
TIDB, порт назначения -T1DA;
3) хост А отправляет (по соединению TIDA - TIDB) команду DATA и блок данных. Пакет также содержит номер блока.
Для работы по протоколу TFTP в Delphi используются два компонента: IdTrivialFTP и dTrivialFTPServer.
1.2. Компонент- idTrivialFTP
Компонент IdTrivialFTP реализует функции TFTP-клиента. Создававаемое в работе приложение-клиент должно выполнять следующие функции:
· запись файла на сервер;
· чтение файла с сервера.
Для выполнения данных функций следует указать имя TFТР-сервера с помощью свойства Host компонента IdTrivialFТР. Например:
IdTrivialFTPl.Host:= Edit1.Text.
По умолчанию свойство Port компонента IdTrivialFTP имеет значение - 69.
Передача файла на сервер выполняется с помощью метода:
IdTrivialFTP1.Put(const LocalFile:String; const ServerFile:String;), где LocalFile - имя локального файла, содержимое которого записывается на сервер, a ServerFile - имя, под которым локальный файл записывается на сервер.
Чтение файла с сервера выполняется с помощью метода:
IdTrivialFTP1.Get IdTrivialFTP1.Get (const ServerFile:String; DestinationStream: TStream;),
где ServerFile - имя удаленного файла, содержимое которого считывается с сервера, a DestinationStream - объект «поток», создаваемый клиентом.
1.3. Компонент IdTrivialFTPServer
Компонент IdTrivialFTPServer реализует функции TFTP-сервера. Создаваемое в работе приложение-сервер должно выполнять следующие функции:
· выбор рабочего каталога;
· запись клиентского файла на сервер;
· передачу файла от сервера к клиенту.
По умолчанию свойство DefaultPort компонента IdTrivialFTPServer имеет значение -69.
Для перевода TFTP-сервера в состояние ожидания запросов от клиента необходимо установить свойство сервера Active в состояние True. Например: IdTrivialFTPServer1.Active:=True.
TFTP-сервер самостоятельно выполняет прием и передачу файлов, то есть программировать данные операции нет необходимости. Но для обеспечения защиты своих каталогов и файлов сервер должен проверять корректность запросов пользователей.
При получении запросов пользователей на сервере происходят следующие события.
• OnReadFile - событие происходит при появлении запроса пользователя на чтение файла с сервера. Программное обеспечение сервера может выполнить дополнительную проверку на допустимость чтения указанного в запросе файла;
• OnWriteFile - событие происходит при появлении запроса пользователя на запись файла на сервер. Программное обеспечение сервера может выполнить дополнительную проверку, например, имеет ли данный пользователь права на запись файла на сервер;
• OnTransferComplete - событие происходит при завершении операции чтения/записи файлов с сервера. Программное обеспечение сервера может использовать данное событие, например, для сбора статистической информации.
2. ЗАДАНИЕ ПО ПРАКТИЧЕСКОМУ ЗАНЯТИЮ
2.1. Создание серверного приложения
Создайте приложение, изображенное на рис. 1.
Рис. 1
Для создания серверного приложения выполните следующие действия.
1) Создайте новое приложение и перенесите на форму компоненты, перечисленные в табл. 1.
Таблица 1
Компонент | Класс | Описание |
Edit1 | TEdit | Окно ввода, в котором отображается выбранный рабочий каталог |
Label1 | TLabel | Метка «Рабочий каталог» |
Memo1 | TMemo1 | Многострочное окно ввода, в котором отображается информация о работе TFTP-сервера |
DirectoryListBox1 | TDirectoryList-Box1 | Окно выбора рабочего каталога (закладка Win 3.1 Палитры компонентов) |
DriveComboBox1 | TDriveComboBox1 | Окно выбора логического диска, на котором будет располагаться рабочий каталог (закладка Win 3.1 Палитры компонентов) |
IdTrivialFTPServer1 | TIdTrivialFTPServer | ТFTР-сервер (закладка Indy Servers Палитры компонентов) |
2) Для события формы OnCreate напишите следующий программный код:
procedure TForm1.FormCreate(Sender: TObject);
begin
// Определение корневого каталога
Edit1.Text:= GetCurrentDir;
//Активизация TFTР-сервера
IdTrivialFTPServerl.Active:=True;
end;.
3) Для события OnChange компонента DriveСomboBox1 напишите следующий программный код:
procedure TForm1.DriveComboBox1Change(Sender: TObject);
begin
DirectorylistBox1.Drive:= DriveComboBoxl.Drive;
end;.
С помощью представленного программного кода для компонента DirectoryListBoxl выбирается текущий логический диск.
4) Для события OnChange компонента DriveComboBox1 напишите следующий программный код:
procedure TForm1.DirectoryListBoxlClick(Sender: TObject);
begin
Edit1.Text:=DirectoryListBoxl.GetItemPath(DirectoryListBox1.ItemIndex);
end;.
Этот программный код заносит в окно Edit1 выбранный рабочий каталог.
5) Для события OnReadFile компонента IdTrivialFTPServer1 напишите следующий программный код:
procedure TForm1.IdTrivilFTPServerlReadFile(Sender: TObject;
var FileName: String; const Peerinfo: TPeerlnfo;
var GrantAccess: Boolean; var A Stream: TStream;
var FreeStreamOnComplete: Boolean);
VAR
s: String;
begin
FreeStreamOnComplete:= false;
s:=’ ~отказано';
try
If GrantAccess then
Begin
s:='- предоставлен';
end;
finally
memo1.Lines.Add(Format('%s: %d - Доступ по чтению к %s %s',
[PeerInfo.PeerIP, PeerInfo.PeerPort, Filename, s]));
end;
end;.
Событие возникает, когда клиент обращается к серверу с запросом на чтение файла. Если доступ к рабочему каталогу разрешен, сервер начинает процесс передачи файла клиенту. Приведенный программный код проверяет, разрешен ли доступ и выводит в окно Memo1 справочную информацию.
6) Для события OnWriteFile компонента IdTrivialFTPServer1 напишите следующий программный код:
procedure TForm1.IdTrivialFTPServer1WriteFile(Sender: TObject;
var FileName: Siring; const PeerInfo: TPeerInfo;
var GrantAccess: Boolean; var AStream: TStream;
var FreeStreamOnComplete: Boolean);
VAR
s: String;
begin
FreeStreamOnComplete:=false;
s:='- отказано';
try
If Grant Access then
begin
s:='- предоставлен';
end;
finally
memo1.Lines.Add(Format('%s: %d - Доступ по записи к %s %s',
[PeerInfo.PeerIP, PeerInfo.PeerPort.Filename,s]));
end;
end;.
Событие возникает, когда клиент обращается к серверу с запросом на запись файла в рабочий каталог сервера. Если доступ к рабочему каталогу разрешен, сервер начинает процесс записи получаемого клиентского файла. Приведенный программный код проверяет, разрешен ли доступ и выводит в окно Memo1 справочную информацию.
7) Для события OnTransferComplete компонента IdTrivialFTPServer1 напишите следующий программный код:
procedure TForm1.IdTrivialFTPServer1TransferComplete(Sender: TObject; const Success: Boolean; const PeerInfo: TPeerInfo; AStream: TStream;
const WriteOperation: Boolean);
Var s: String;
begin
try
If Success then s:= ' выполнена'
else s:=' прервана';
memo1.Lines.Add(Format('%s: %d -Передача %s',
[PeerInfo.PeerIP, PeerInfo.PeerPort, s]));
finally
AStream.Free;
end;
end;.
Событие возникает, когда на сервере закончен процесс чтения или записи файла, получаемого or клиента или передаваемого клиенту. Приведенный программный код проверяет, успешно или нет выполнена операция и выводит в окно Memo1 справочную информацию.
8) Откомпилируйте созданное приложение.
2.2. Создание клиентского приложения
Создайте приложение, изображенное на рис. 2.
Рис. 2
Для создания клиентского приложения выполните следующие действия.
1) Создайте новое приложение и перенесите на форму компоненты, перечисленные в табл. 2.
2) Для события OnClick кнопки «Выбор файла» напишите следующий программный код:
procedure TForm1.Button1Click(Sender: TObject);
begin
If Open Dialog1.Execute then
Edit3.Text:= OpenDialog1.FileName;
end;.
Представленный программный код записывает и окно Edit3 имя локального файла. Этот файл будет передаваться на TFTP-сервер при выполнении операции записи на сервер. В него же будет считываться файл с TFTP-сервера при выполнении операции чтения.
Компонент | Класс | Описание |
Edit1 | TEdit | Окно ввода адреса TFТР-сервера |
Edit2 | TEdit | Окно ввода имени удаленного файла |
Edit3 | TEdit | Окно ввода имени локального файла |
Label1 | TLabel | Метка «Адрес ТFTP-сервера» |
Label2 | TLabel | Метка «Имя удаленного файла» |
Label3 | TLabel | Метка «Имя локального файла» |
OpenDialog1 | TOpenDialog | Компонент «Диалоговое окно выбора файла» (закладка Dialogs Палитры компонентов) |
IdTrivialFTPS1 | TIdTrivialFTP | TFTP-клиент (закладка Indy Clients Палитры компонентов) |
Button1 | TButton | Кнопка «Выбор файла» |
Button2 | TButton | Кнопка «Запись файла на сервер» |
Button3 | TButton | Кнопка «Чтение файла с сервера» |
3)Для события OnClick кнопки «Запись файла на сервер» напишите следующий программный код:
procedure TForm1.Button2Click(Sender: TObject);
Var s: String;
begin
// Определение имени удаленного файла
S:=Edit2.Text:
// Если имя удаленного файла не введено,
// то файл будет записан на сервер под именем локального файла
If s=" then s:=ExtractFilename(Edit3.Text);
With IdTrivialFTP1 do
begin
// Определение имени или адреса сервера
Host:=Edit1.Text;
// Запись на сервер локального файла под новым именем
Put(Edit3.Text,s)
end;
end;.
4) Для события OnClick кнопки «Чтение файла с сервера» напишите следующий программный код:
procedure TForm1.Button3Click(Sender: TObject);
VAR
strm TFileStream;
s: String;
begin
// Определение имени локального файла
s:= Edit3.Text;
//Если имя локального файла не введено,
// то файл будет записан на сервер под именем удаленного файла
If s=” then ExtractFilename(Edit2.Text);
strm:= TFileStream.Create(s, fmCreate);
With IdTrivialFTP1 do
try
// Определение имени или адреса сервера
Host:=Edit1.Text;
// Чтение удаленного файла с сервера
Get(Edit2.Text, strm);
Finally
strm.Free;
end;
end;.
5) Откомпилируйте созданное приложение.
6) Проверьте совместную работу серверного и клиентского приложений.
ЛИТЕРАТУРА
Киммел П. Создание приложений в Delphi /Пер. с англ. М., Издательский дом «Вильямс», 2003. 640 с.
КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Опишите алгоритм работы протокола TFTP.
2. Перечислите отличия протокола TFTP от протоколов SNTP и FTP.
3. С помощью какого метода TFTP-клиент передает данные на сервер?
4. С помощью какого метода TFTP-клиент запрашивает данные с сервера?
5. Как перевести TFTP-сервер в состояние ожидания запросов от клиентов?
6. Почему протокол TFTP не обеспечивает надежную передачу данных?
7. Какой номер порта по умолчанию использует протокол TFTP?
ЗАНЯТИЕ №18
СОЗДАНИЕ HTTP -КЛЕНТА
Приложение «HTTP-клиент» должно выполнять следующие запросы протокола HTTP:
· GET - чтение html-страницы с сервера Internet;
· TRACE - тестирование сервера Internet. Запрос действует аналогично запросу GET, но возвращает клиенту только НТТР-заголовок, тем самым проверяя наличие на сервере определенной html-страницы;
• PUT запись html-страницы на сервер Internet.
Цель работы: получить практику в программировании клиентского приложения при помощи компонента IdHTTP для передачи запросов WEB-сервер.
1. ТЕОРЕТИЧЕСКОЕ ВВЕДЕНИЕ
В теоретическом введении рассматриваются следующие свойства и методы компонента IdHTTP.
1.1. Свойства и методы компонента IdHTTP
Компонент IdHTTP используется для обеспечения сетевого проток HTTP (поддерживаются версии 1.0 и 1.1, включая операции GET, POST и HEAD). Кроме того, обеспечивается поддержка аутентификации и применения прокси-серверов.
1.1.1. Метод GET
Метод GET предназначен для чтения html-страниц с WEB-сервера. В компоненте IdНТТР реализовано два варианта данного метода.
· Procedure Get(AURL: String; const AResponseContent: TStream), где AURL - URL-pecypca (html-страницы), находящегося на сервере; AResponseContent - поток данных клиента, куда будет записываться ответ сервера.
· Function Get (AURL: String): Siring,
где AURL - URL-pecypca (html-странницы), находящегося на сервере. Функция возвращает ответ от сервера в виде строки.
1.1.2. Метод TRACE
Метод TRACE предназначен дли чтения заголовков html-страниц c WEB-сервера. В компоненте IdHTTP реализовано два варианта этого метода:
· Procedure Trace(AURL: String; const AResponseContent: TStream), где AURL - URL-ресурса, находящегося на сервере;
AResponseContent - поток данных клиента, куда будет записываться ответ сервера;
· Function Trace (AURL: String): String,
где AURI - URL-ресурса, находящегося на сервере.
Функция возвращает ответ от сервера в виде строки.
1.1.3. Метод PUT
Метод PUT предназначен для записи html-страниц на WEB-сервер. В компоненте IdHTTP реализовано два варианта метода:
· Procedure Put(AURL: String; const ASource: TStream;
AResponseContent: TStream),
где AURL - URL-ресурса. Под этим именем данные клиента будут записываться на сервер;
ASource - поток данных клиента, записываемый на сервер. Этот поток должен быть связан с определенным файлом на компьютере клиента;
AResponseContent - поток данных клиента, куда будет записываться ответ сервера;
· Function Put (AURL: String; const ASource: TStream): String,
где AURL - URL-ресурса, находящегося на сервере:
ASource - поток данных клиента, записываемый на сервер. Этот поток должен быть связан с определенными файлами на компьютере клиента.
Функция возвращает ответ от сервера в виде строки.
2. ЗАДАНИЕ ПО ПРАКТИЧЕСКОМУ ЗАНЯТИЮ
2.1. Создание HTTP-клиента
Разработайте приложение, изображенное на рис. 1-3.
Рис.1
Рис.2
Рис. 3
Для создания приложения перенесите на форму компоненты, приведенные в табл. 1.
Таблица 1
Компоненты, устанавливаемые на форме
Компонент | Класс | Описание |
IdHTTP1 | TldHTTP | HTTP-клиент (страница Indy Clients Палитры компонентов) |
OpenDialog1 | TOpenDialog | Компонент «Открытие файла» (страница Dialogs Палитры компонентов) |
StatusBar1 | StatusBar | Компонент «Панель состояния» (страница Win32 Палитры компонентов) |
PageControl 1 | TPageControl | Компонент «Многостраничная панель» (страница Win32 Палитры компонентов). На ней следует создать три страницы с названиями - GET, TRACE и PUT |
Label1 | TLabel | Метка «Введите URL». Располагается на странице GET многостраничной панелиPageControl1 |
Label 2 | TLabel | Метка «HTTP-ответ». Располагается на странице GET, многостраничной панели PageControl1 |
Edit1 | TEdit | Окно ввода URL. Располагается на странице GET многостраничной панели PageControl1 |
Memo1 | TMemo | Многострочное окно. Располагается на странице GET многостраничной панели PageConlrol1. Предназначено для вывода им экран запрошенной с сервера страницы |
Button1 | TButton | Кнопка «GET (1 метод)». Располагается на странице GET многостраничной панели PageControl1 |
Button3 | TButton | Кнопка «GET (2 метод)». Располагается на странице GET многостраничной панели PageControl1 |
Label4 | TLabel | Метка «Введите URL». Располагается на странице TRACE многостраничной панели PageControl1 |
Label5 | TLabel | Метка «Заголовок ответа». Располагается на странице TRACE многостраничной панели PageControl1 |
Edit2 | TEdit | Окно ввода URL. Располагается на странице TRACE многостраничной панели PageControl1 |
Компонент | Класс | Описание |
Memo2 | TMemo | Многострочное окно. Располагается на странице TRACE многостраничной панели PageControl 1. Предназначено для вывода на экран заголовка запрошенной с сервера страницы |
Button2 | TButton | Кнопка «TRACE» располагается на странице TRACE многостраничной панели Page Control 1 |
Label3 | TLabel | Метка «Имя локального файла». Располагается на странице PUT многостраничной панели PageControl 1 |
Label3 | TLabel | Метка «Имя удаленного файла». Располагается на странице PUT многостраничной панели PageControl 1 |
Edit3 | TEdit | Окно ввода имени локального файла. Располагается на странице PUT многостраничной панели PageControl 1 |
Edit4 | TEdit | Окно ввода имени удаленного файла. Располагается на странице PUT многостраничной панели PageControl 1 |
Button4 | TButton | Кнопка «Выбор». Располагается на страниц PUT многостраничной панели PageControl1 Предназначена для выбора локального файла, содержимое которого будет записываться на сервер |
Button5 | TButton | Кнопка «Запись на сервер». Располагается на странице PUT многостраничной панели PageControl 1. Предназначена для выбора имени удаленного файла, под которым локальный файл будет записываться на сервер |
Далее определите события.
1) Для события OnCreate формы Form 1 запишите следующий программный код:
procedure ТForm1.FormCreate(Sender: TObjeсt):
begin
Edit1.Text:='http://myself/www/index.html';
Edit2.Text:='http://myself/www/index.html';
Edit4.Text:= 'http://myself/www/fl.html';
Memo1.Clear;
Statusbarl.SimplePanel:= True;
end;
Этот программный код устанавливает начальные значения для URL и определяет панель состояния как простую, то есть состоящую из одной панели, содержимое которой определяется свойством SimpleText.
2) Для события OnClick кнопки «GET (1 метод)» запишите следующий программный код:
procedure TForml.ButtonlClick(Sender: TObject);
Var s: TStringStream;
begin
try
s:=TStringStream.Create(");
IdHTTPI.Get(Edit1.Text,s);
s.Position:=0;
Memo1.Lines.LoadFromStream(s);
Statusbar1.SimpleText:='GET: OK';
except
on e: Exception do
begin
ShowMessage('Error:' + e.Message);
end; // on Exception
end;
end;
Представленный программный код реализует метод GET компонента IdHTTP, причем метод GET вызывается как процедура. Создается поток строк - s. В этот поток считывается содержимое выбранного файла с сервера, а затем методом Memo1.Lines.LoadFromStream поток записывается в поле Memo1.
3) Для события OnClick кнопки «GET (2 метод)» запишите следующий программный код:
procedure TForm1.Button3Click(Sender: TObject);
begin
try
If not IdHTTP1. Connected then IdHTTP1.Connect;
If IdHTTP1.Connected then
begin
StatusBar1.SimpleText:= 'Connect: OK';
try
memo1.Lines.Text:= IdHTTP1.Get(Edit1.Text);
StatusBar1.SimpleText:='Метод GET: OK';
except
StatusBarl.SimpleText:='Метод GET: Объект не найден';
end;
end
else
StatusBarl.SimpleText:='Метод GET: Not connected';
except
StatusBarl.SimpleTexl:= 'Метод GET:
Ошибка при установлении соединения';
end;
end;
Программный код реализует метод GET компонента IdHTTP, причем метод GET вызывается как функция. Свойству memol.Lines.Text присваивается результат работы метода IdHTTP.Get
.4) Для события OnClick кнопки «TRACE» запишите следующий программный код:
procedure TForm1.Button2Click(Sender: TObject);
Var s: TStringStream;
begin
try
s:= TstringStream.Create(");
IdHTTP1.Trace(Edit2.Text,s);
s.Position:=0;
Memo2.Lines.LoadFromStream(s):
Statusbar1.SimpleText:= 'TRACE: OK';
except
Statusbarl.SimpleText:='TRACE: Error';
end;
end;
Этот программный код реализует метод TRACE компонента IdHTTP, причем метод TRACE вызывается как процедура. Создается поток строк – s. В этот поток считывается заголовок выбранного файла с сервера, а затем методом Mеmo2.Lines.LoadFromStream поток записывается в поле Меmo2.
5) Для события OnClick кнопки «Выбор» запишите следующий программный код:
procedure TForm1.Button4Click(Sender: TObject);
begin
If OpenDialogl.Execute then
Edit3.Text:= OpenDialogl.FileName:
end;
С помощью этого кода выбирается локальный файл на компьютере клиента, который будет записываться на сервер.
6) Для события OnClick кнопки «Запись на сервер» запишите следующий программный код:
procedure TForm1.Button5Click(Sender: TObject);
Var F: TFileStream;
s1: String;
begin
try
f:= TFileStream.Create(Edit3.Text. fmOpenRead);
s1:=IdHTTP1.Put(Edit4.Text, f);
Statusbar1.SimpleText:='PUT: OK';
f,Free;
except
Statusbar 1.SimpleText:= 'PUT: Error';
end;
end;
Программный код реализует метод PUT компонента IdHTTP, причем метод PUT вызывается как функция.
ДОПОЛНИТЕЛЬНОЕ ЗАДАНИЕ
1. Запрограммируйте метод TRACE как функцию.
2. Запрограммируйте метод PUT как процедуру.
ЛИТЕРАТУРА
Киммел П. Создание приложений в Delphi /Пep. с англ. М, Издательский дом «Вильямс», 2003. 640 с.
КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Перечислите основные методы компонента IdHTTP:
2. Какой Метой протокола HTTP используется для записи файлов на сервер?
3. Какой метод протокола HTTP используется для тестирования сервера?
4. Как изменить приложение таким образом, чтобы файл с сервера записывался не в поле Memo, а в какой-либо файл на компьютере клиента? Каким должен быть тип переменной s в данном случае?
ЗАНЯТИЕ № 19
СОЗДАНИЕ WEB-БРАУЗЕРА
Цель работы: практически освоить приемы работы с компонентом WebBrowser для программирования клиентских приложений при работе с серверами Internet.
1. ТЕОРЕТИЧЕСКОЕ ВВЕДЕНИЕ
Web-браузер должен обладать следующими основными возможностями:
· заносить URL, для связи с Internet;
· переключаться в ранее открытые страницы и документы;
· иметь строку состояния, отображающую процесс загрузки документа.
Для построения Web-браузера средствами Delphi используется компонент WebBrowser, расположенный на странице Internet Палитры компонентов.
Основным методом компонента WebBrowser является метод Navigate, например, WebBrowser1.Navigate('D:\tests\file.html').
С помощью метода Navigate ищется указанные файл или адрес URL и загружается в браузер затребованный ресурс.
Для создания Web-браузера, обладающего требуемыми функциями необходимо использовать обработчики следующих событий компонент WebBrowser:
· OnBeforeNavigate2 (функция-обработчик данного события имеет имя -WebBrowserlBeforeNavigatе2) - наступает перед переходом браузера на новый документ. Это событие наступает независимо от того, чем вызван этот переход: выполнением метода Navigate или переходом по ссылке в окне браузера. Передаваемый в обработчик параметр «URL» является адресом, по которому будет осуществляться переход. Параметр «Cancel», если задать ему значение false, прервет переход на новый документ;
· OnProgressChange - (функция-обработчик этого события имеет имя WebBrowserlProgressChange). Это событие происходят во время загрузки страницы в браузер. Для определения имени загружаемого документа используется свойство «LocationName» компонента WebBorowserl. В обработчик события передаются параметры Progress - объем загружаемого документа и ProgrеssMax - полный объем документа. Таким образом, появляется возможность отображать ход загрузки больших документов. Когда загрузка завершена, значение Progress становится равным – 1.
2. ЗАДАНИЕ ПО ПРАКТИЧЕСКОМУ ЗАНЯТИЮ
Для создания приложения WEB-БРАУЗЕРА, изображенного па рис. 1 выполните следующие действия.
1) Создайте проект.
2) Добавьте на форму меню MainMenu со страницы Standart Палитры компонентов. Меню должно иметь вид, изображенный на рис. 2.
3) Добавьте на форму панель CoolBar (страница Win32 Палитры компонентов). Перенесите на панель CoolBar инструментальную панель ToolBar (страница Win32 Палитры компонентов).
Рис. 1
Рис. 2
4) Установите в true ее свойство ShowCaptions, чтобы можно было видеть надписи на кнопках.
a) Введите на панель ToolBar щелчками Правой кнопки «мыши» три кнопки - «Назад», «Вперед» и «Домашняя страница». Установите для каждой из них соответствующую надпись в поле Caption.
b) Для первых двух кнопок («Назад» и «Вперед») задайте свойство Enabled равным false, так как в момент открытия приложения перемещаться будет некуда.
с) Для кнопок можно задать пиктограммы. Для этого перенесите на форму список пиктограмм ImageList (страница Win32 Палитры компонентов). Щелкните два раза на списке ImageList для вызова диалога добавления пиктограмм. Для панели ToolBar установите свойство Images равным ImageList1 для связи панели ToolBar со списком пиктограмм.
4) Перенесите на панель CoolBar компонент выпадающего списка ComboBox (страница Standart Палитры компонентов). В окне редактирования этого списка пользователь может набирать URL или имя файла документа HTML, а из выпадающего списка выбирать один из ранее просмотренных документов.
5) Установите для панели Coolbar ее свойства AutoSize и ShowText в true. Первое из них обеспечит автоматическое изменение размеров панели при перемещении пользователем расположенных на ней компонентов. А второе обеспечит видимость текстов полоc.
6) Около свойства Bands панели CoolBar щелкните на кнопке с многоточием и в открывшемся окне редактора полос для второй полосы, на которой расположено поле со списком (ComboBox), задайте свойство Text равным «Адрес».
7) Перенесите на форму панель состояния StatusBar (страница Win32 Палитры компонентов). Установите ее свойство SimplePanel в True. Это означает, что панель не будет делиться на несколько панелей.
8) Перенесите на форму компонент WebBrowser (страница Internet Палитры компонентов). Установите свойство Align равным alClient, для того, чтобы окно просмотра HTML-документов занимало всю свободную часть формы. Теперь форма будет иметь вид, показанный на рис. 1.
9) Далее необходимо запрограммировать:
a) для события OnCreate формы Form1 запишите следующий программный код:
procedure TForm1.FormCreate(Sender: TObject);
begin
// В ComboBox 1 записывается домашняя страница
ComboBox1.Text:='http://myself/www/Main1.html';
WebBrowser1.Navigate(ComboBox1.Text);
end;
b) для события OnClick компонента ComboBox запишите следующий программный код:
procedure TForm1.ComboBox1Click(Sender: TObject);
begin
// Web-браузер читает страницу,
//адрес которой указан в текущей строке ComboBox
WebBrowser1.Navigate(ComboBox1.Text);
CoolBarl.Update;
end;
c) для события OnkeyDown компонента ComboBox запишите следующий программный код:
procedure TForml.ComboBox1KeyDown(Sender: TObject; var Key:
Word; Shift: TShiftState);
Begin
//Если нажата клавиша Enter, то Web-браузер считывает страницу
If Key=VK_Return then
begin
WebBrowserl.Navigate(ComboBoxl.Text);
end;
end;
d) для события OnCiick кнопки «Назад» запишите следующий программный код:
procedure TForml.ToolButton1Click(Sender: TObject);
begin
// Выбирается предыдущий адрес
ComboBox1.Text:= ComboBox1.Items[ComboBox1.itemIndex+1];
WebBrowserl.Navigate(ComboBox1.Text);
end;
e) для события OnCiick кнопки «Вперед» запишите следующий программный код:
procedure TForm1.ToolButton2Cleck(Sender: TObject);
begin
// Выбирается следующий адрес
ComboBox1.Text:= ComboBox1.Items[ComboBox1.ItemIndex-1];
WebBrowserl.Navigate(ComboBoxl.Text);
end;
f) для события OnClick кнопки «Домашняя страница» запишите следующий программный код:
procedure TForm1.ToolButton3Click(Sender: TObject);
begin
// определение страницы но умолчанию
ComboBox1.Text:= 'http://myself/www/Main1.html';
WebBrowserl.Navigate(ComboBox1.Text);
end;
g) для события OnBeforeNavigate2 компонента WebBrowserl запишите следующий программный код:
procedure TFortn1.WebBrowser1BeforcNavigate2(Sender: TObject;
const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData,
Headers: OleVariant; var Cancel: WordBool);
// Обработка события перед загрузкой
Var
Index: Integer;
begin
// Управление списком ComboBox1
Index:= ComboBoxl.Items.IndexOf(URL);
If Index=1 then
begin
ComboBox1.Items.Insert(0,URL);
ComboBo1.ItemIndex:=0;
end
else ComboBoxl.ItemIndex:= Index;
// Задание доступности кнопок
If ComboBox1.ItemIndex>0
then ToolButton2.Enabled:= True
else ToolButton2.Enabled:= False;
If ComboBox1.ItemIndex<ComboBoxl.Items.Count-1
then ToolButton1.Enabled:= True
else ToolButton1.Enabled:= False;
end;
В обработчике WebBrowserlBeforeNavigate2 прежде всего определяется методом IndexOf компонента ComboBox 1 индекс нового URL в списке. Если метод IndexOf вернул – 1, значит данного адреса ранее в списке не было. В этом случае он включается методом Insert компонента ComboBox 1 в первую (с индексом 0) позицию списка и индекс списка устанавливается на 0. Если новый адрес уже был в списке, то индекс списка устанавливается равным этому значению. В обоих случаях изменение индекса списка обеспечивает отображение в его окне нового адреса. Далее в обработчике WebBrowserlBeforeNavigale2 устанавливается доступность или недоступность кнопок навигации TooButton2 (Вперед) и ToolButton1 (Назад) в зависимости оттого, каково значение индекса и есть ли в списке предшествующие и последующие документы;
h) для события OnProgressChange компонента WebBrowser1 запишите следующий программный код:
procedure TForml.WebBrowser1ProgressChange(Sender: TObject; Progress,
ProgressMax: Integer);
// Занесение текста в панель состояния
begin
If Progress>0 then
Statusbar1.SimpleText: Format(‘Документа %s: прочитано %d Кбайт
из %d’, [WebBrowser1.LocationName,Progress div l024, Progressmax
div 1024]);
end;
В обработчике WebBrowserlProgressChange использовано свойство компонента WebBrowserl «LocationName» имя загружаемого документа.
n) для щелчка на разделе меню «Открытие файла» запишите следующий программный код:
procedure TForm1.N10Click(Sender: TObject);
begin
// Вызов диалога открытия файла
If OpenDialogl.Execute then
begin
ComboBox1.Text:= OpenDialogl.FileName;
WebBrowser1.Navigate(ComboBox1.Text);
end;
end;
Ими выбранного пользователем файла загружается в свойство Text компонента ComboBoxl.
12) Самостоятельно запрограммируйте все остальные пункты меню, изображенные на рис. 2.
ЛИТЕРАТУРА
1. Озеров В. A. Delphi. Советы программистов. СПб., Символ-Плюс, 2004. 976 с.
2. Архангельский А. Я. Программирование в Delphi б. М., Изд-во БИНОМ, 2002. 1120 с.
КОНТРОЛЬНЫЕ ВОПРОСЫ
1. Из каких частей состоит и для чего используется URL?
2. Перечислите основные свойства компонента WebBrowser.
3. Перечислите основные события компонента WebBrowser.
ЗАНЯТИЕ № 20