Робота з HTTP протоколом в Delphi h2>
В
зв'язку з усе більшою увагою, яке привертає до себе Інтернет, все більше
людей стають зацікавлені в мережних технологіях. Дана стаття присвячена
програмування на Borland Delphi з використанням одного з найпопулярніших
Інтернет-протоколів - HTTP. P>
А
саме, тут ми розглянемо компонент TNMHTTP (NetMasters HTTP), який можна
виявити на вкладці FastNet палітри компонентів Дельфі. p>
Почнемо
з теорії. Якщо Ви вже знаєте, що таке HTTP і навіщо він потрібен, то пропустіть
наступний розділ. p>
Навіщо потрібен HTTP h2>
Отже,
де ж використовується HTTP? Якщо Ви хоча б трохи заглядали на
Інтернет-сторінки і зустрічалися з терміном Web, то, напевно, звернули увагу
на те, що адреси сторінок, як правило, починаються з http://. Протокол HTTP
(HyperText Transfer Protocol) дозволяє приймати і надсилати не тільки
гіпертекстові документи (типу html), а й будь-які інші (тексти (txt),
зображення (gif, jpg), і т.д.). Нижче наведені типові завдання, для виконання
яких необхідно використовувати HTTP: p>
Браузери
- Програми, що дозволяють переглядати Інтернет-сторінки; p>
Скачівальщікі
- Програми, що дозволяють скачувати з Інтернету сторінки, малюнки та інші
документи; p>
Чати
- Програми, що дозволяють спілкуватися по мережі. Часто документи HTTP використовуються
для зберігання повідомлень (як, наприклад, у конференціях). p>
--
Це лише список деяких з стандартних напрямків програмування з
використанням HTTP. Ви можете застосовувати цей протокол для будь-яких своїх цілей.
Наприклад, автоматичні системи оновлення даних, посилка запитів в
Інтернетівські бази, та ще безліч усіляких інших можливостей! P>
Короткий опис властивостей, методів і подій h2>
Нижче
наведена таблиця, яка містить найбільш короткий опис основних властивостей,
методів і подій компонента TNMHTTP: p>
Властивості p>
Body
- Рядок, що містить або шлях до файлу, в який буде записано тіло
http-документа (якщо св-во InputFileMode одно True), або безпосередньо сам
тіло (якщо св-во InputFileMode одно False). Тип: string; p>
Header
- Рядок, що містить або шлях до файлу, в який буде записаний заголовок
http-документа (якщо св-во InputFileMode одно True), або безпосередньо сам
заголовок (якщо св-во InputFileMode одно False). Тип: string; p>
HeaderInfo
- Структура, що містить різну інформацію про http-документі (детальніше див
help-файлі). Тип: THeaderInfo; p>
InputFileMode
- Тип запису результату. Значення True - запис у файли, вказані у властивостях
Body і Header, False - запис у самі ці властивості. Тип: Boolean; p>
OutputFileMode
- Тип відсилаються даних (методами Put, Post і Trace). Значення True - дані
для відправки містяться у файлах, зазначених при виклику цих методів, а False --
в самих аргументах цих методів. Тип: Boolean; p>
Далі
деякі властивості, успадковані від TPowerSock: p>
BytesRecvd,
BytesSent, BytesTotal - кількість відправлених, прийнятих і загальна кількість
байтів відповідно. Тип: LongInt; p>
Connected
- Показує, встановленому в даний момент з'єднання. Тип: Boolean; p>
BeenCanceled
- Показує, чи було перервано з'єднання з сервером. Тип: Boolean; p>
Host
- Рядок для хост-ім'я віддаленого комп'ютера. Заповнювати не треба, тому що
це властивість встановлюється автоматично при виклику методів Get, Put, Post і
т.д. Тип: string. Port - Integer, що містить порт віддаленого комп'ютера
(заповнюється теж автоматично); p>
TimeOut
- Таймаут в мілісекундах. Тип: Integer; p>
Ще
є безліч властивостей, але я поки зупинюся на вже перерахованих. За
додатковою інформацією звертайтеся до help-у за Дельфі. p>
Методи p>
Get (URL:
string) - надсилає запит на вказаний URL. Дані після виконання цього
запиту записуються у файли чи в самі властивості Body і Header (в залежності
від значення властивості InputFileMode); p>
Head (URL:
string) - надсилає запит на вказаний URL. Дані після виконання цього
запиту записуються у файл або в саме властивість Header (в залежності від
значення властивості InputFileMode). На відміну від методу Get, виклику Head
запит надсилається тільки на http-заголовок документа; p>
Post (URL,
PostData: string) - надсилає запит на зміну http-документа (з адресою URL)
на дані, що містяться в параметрі PostData. Якщо OutputFileMode дорівнює True,
то в PostData повинен бути шлях до файлу, який містить потрібні дані. p>
Put (URL,
PutData: string) - надсилає запит на створення http-документа (з адресою URL),
що містить дані, передані в параметрі PutData. Якщо OutputFileMode дорівнює
True, то в PostData повинен бути шлях до файлу, який містить потрібні дані. P>
Trace (URL,
TraceData: string) - надсилає запит на отримання оцінних даних (для
налагодження з'єднання з HTTP-сервером). Дані для запиту потрібно вказати в
параметрі TraceData. Якщо OutputFileMode дорівнює True, то в TraceData повинен
міститися шлях до файлу, який містить потрібні дані. p>
Delete (URL:
string) - надсилає запит на видалення http-документа (з адресою URL). p>
Далі
деякі методи, успадковані від TPowerSock: p>
Abort
і Cancel - переривають з'єднання та обмін даними; p>
Disconnect
- Від'єднання від HTTP-сервера; p>
Події h2>
OnAuthenticationNeeded
- Виникає, коли сервер вимагає зазначення імені користувача та пароля. У
обробнику цієї події (якщо вона виникне) Ви повинні відповісти сервера,
запону потрібними значеннями відповідні змінні. Примітка: Перед
встановленням з'єднання можна відразу заповнити поля UserID і Password в
властивості HeaderInfo; p>
OnAboutToSend
- Виникає, коли компонент TNMHTTP збирається відправляти дані (запит). У
обробнику цієї події можна заповнити додатковою інформацією властивість
SendHeader; p>
OnFailure
- Виникає, коли поточна операція завершилася невдало, тобто відбулася
помилка; p>
OnRedirect
- Виникає, сервер переадресував посилання з вказаної URL на іншу посилання.
Встановивши параметр handled в значення True можна заборонити переадресацію і зупинитися
на запитаної URL. Значення за замовчуванням - False; p>
OnSuccess
- Виникає, коли поточна операція завершилася успішно, тобто запит був
виконаний без помилок; p>
Далі
деякі методи, успадковані від TPowerSock: p>
OnConnect
- Виникає, коли з'єднання з сервером успішно встановлено; p>
OnDisconnect
- Виникає, коли з'єднання з сервером завершено; p>
OnConnectionFailed
- Виникає, коли з'єднання з сервером встановити не вдалося; p>
OnError
- Виникає, коли остання операція була завершена з помилкою; p>
OnHostResolved
- Виникає, коли від DNS отримано IP-адресу зазначеного хоста; p>
OnInvalidHost
- Виникає, коли DNS повернув помилку при спробі визначити IP-адресу зазначеного
хоста; p>
OnPacketRecvd
- Виникає, коли значення властивостей BytesRecvd і BytesTotal змінені, тобто була
прийнята нова порція даних від сервера; p>
OnPacketSent
- Виникає, коли значення властивостей BytesSent і BytesTotal змінені, тобто була
відправлена нова порція даних на сервер; p>
OnStatus
- Виникає, коли статус компонента був змінений (для оновлення візуального
сповіщення користувача); p>
Практика і приклади h2>
Ну
а тепер приступимо до самого головного методу вивчення - на прикладах. p>
І
самий перший приклад - програма, що дозволяє визначити, чи існує заданий
URL: p>
Приклад
1. Перевірка існування зазначеної URL p>
(...
Тут йде заголовок файлу і визначення форми TForm1 і її примірника Form1) p>
(У
форму потрібно помістити кнопку TButton і одне поле TEdit. При натисканні на p>
кнопку
викликається обробник події OnClick - Button1Click. Перед цим у p>
TEdit
потрібно ввести адресу URL. НЕ ЗАБУДЬТЕ Помістити в ФОРМУ КОМПОНЕНТ TNMHTTP!) P>
procedure Button1Click (Sender:
TObject); p>
begin p>
(Питаемя отримати заголовок) p>
NMHTTP1.Head (Edit1.Text); p>
(Якщо
URL невірний, то тут вискочить помилка) p>
end; p>
Наступний
приклад - скачування відразу декількох URL одночасно. Треба зауважити, що
багато програмісти нехтують багатозадачністю Windows (неважливо, як вона
реалізована, мова зараз не про це). У Дельфі дуже легко створювати окремі,
підлеглі Вашій програмі процеси (а точніше - потоки) за допомогою базового
класу TThread. Але про це ми поговоримо іншим разом (в іншій статті). P>
Приклад
3. Одночасне скачування зазначених URL в заданий каталог p>
//
Тут йде заголовок файлу і визначення форми TForm1 і її примірника Form1 p>
//
Опис класу окремого процесу p>
type p>
THTTPThread
= Class (TThread) p>
private p>
(Для
кожного процесу - створюємо свій компонент TNMHTTP) p>
FHTTP:
TNMHTTP; p>
protected p>
//
Execute викликається при запуску процесу; override - замінюємо p>
//
існуючу процедуру базового класу TThread p>
procedure
Execute; override; p>
//
DoWork - створена нами функція, виконання якої синхронізується в Execute p>
procedure
DoWork; p>
public p>
//
URL - створена нами рядок, що вказує процесу, який URL йому потрібно завантажити p>
URL:
string; p>
end; p>
//
У форму потрібно помістити три кнопки TButton, одне поле TEdit і один список p>
//
TListBox. При натисненні на кнопку Button1 викликається обробник події p>
//
OnClick - Button1Click. Перед цим у TEdit потрібно ввести шлях до каталогу, в p>
//
якому будуть зберігатися завантажені файли, а ListBox1 потрібно заповнити списком p>
//
URL-ів для скачування (за допомогою кнопок Add (Button2) і Delete (Button3 )). p>
procedure
TForm1.Button3Click (Sender: TObject); p>
begin p>
(Видалення
виділеного URL зі списку) p>
if ListBox1.ItemIndex> = 0 then p>
ListBox1.Items.Delete (ListBox1.ItemIndex); p>
end; p>
procedure
TForm1.Button2Click (Sender: TObject); p>
var s: string; p>
begin p>
(Додавання URL в список) p>
s: = InputBox ( 'Додати', 'Введіть URL :',''); p>
if s''then p>
ListBox1.Items.Add (s); p>
end; p>
procedure
TForm1.Button1Click (Sender: TObject); p>
var i: Integer; p>
begin p>
(Перевірка
на існування каталозі) p>
if Length (Edit1.Text)> 0 then p>
if not DirectoryExists (Edit1.Text)
then p>
MkDir (Edit1.Text); p>
(Далі
йде створення для кожного URL в списку свого процесу) p>
for i: = 0 to ListBox1.Items.Count-1
do begin p>
with THTTPThread.Create (True) do
begin p>
(Створюємо
призупинену завдання, вказуємо їй її URL і запускаємо її) p>
URL: = ListBox1.Items [i]; p>
Resume; p>
end; p>
end; p>
end; p>
// Оператори процесу THTTPThread p>
procedure THTTPThread.Execute; p>
begin p>
//
Робимо так, щоб кожний процес виконувався одночасно з іншими (синхронізація)) p>
Synchronize (DoWork); p>
end; p>
procedure THTTPThread.DoWork; p>
var i: Integer; p>
begin p>
(Створюємо компонент TNMHTTP) p>
FHTTP: = TNMHTTP.Create (Form1); p>
(Результат
треба записувати у файли) p>
FHTTP.InputFileMode: = True; p>
(Підбираємо
імена для файлів) p>
i: = 1; p>
while
FileExists (Form1.Edit1.Text + 'page' + IntToStr (i) + '. Htm') do p>
Inc (i); p>
(Зазначаємо,
в які саме файли класти результат) p>
FHTTP.Body: = Form1.Edit1.Text + 'body' + IntToStr (i) + '. htm'; p>
FHTTP.Header: =
Form1.Edit1.Text + 'header' + IntToStr (i) + '. Txt'; p>
(Намагаємося
послати запит) p>
FHTTP.Get (URL); p>
(Перед
завершенням процесу не забуваємо звільнити пам'ять з-під компонента) p>
FHTTP.Free; p>
end; p>
ПРИМІТКА:
Щоб завершити деякий процес (Thread), потрібно викликати метод Terminate
класу цього процесу. Призупинити процес можна оператором Suspend, а
продовжити виконання - Resume. Також можна налаштувати пріоритет кожного
окремого процесу через властивість Priority. p>
Непоганий
приклад роботи з процесами можна знайти в підпапці DemosThreads папки, куди Ви
встановили Delphi. p>
Зауваження
за алгоритмами типових завдань p>
Якщо
Ви збираєтеся створити скачівалку сайтів, то Вам необхідно враховувати наступне
(вирішити наступні проблеми): p>
Потрібно
завантажувати не тільки саму сторінку у форматі HTML, а й усі вхідні в неї
малюнки (gif, jpg, і т.д.); p>
в
деяких випадках зручно викачувати не одну сторінку, а декілька сторінок,
посилання на які знаходяться на першій з викачуваних сторінок. При цьому потрібно
враховувати, що на сторінці можуть знаходитися і посилання на інші сайти, тому
необхідно аналізувати завантажує посилання (щоб випадково не завантажити весь
Інтернет). Для вирішення завдання зі скачуванням декількох сторінок потрібно
використовувати рекурсію; p>
необхідно
якісно інформувати користувача про хід закачування. Тобто показувати загальне і
викачане кількість інформації; p>
після
скачування потрібно замінити інтернетівські посилання на локальні, щоб можна було
переглядати сторінки в режимі offline. p>
Список літератури h2>
Для
підготовки даної роботи були використані матеріали з сайту http://www.hostmake.ru/
p>